今天项目加新需求,添加积分过期提醒功能:

第一反应就用系统的UIAlertViewController,但是message中积分是需要红色显示。

//        let str = "尊敬的顾客,您有1000积分即将过期,请尽快使用"
// let attributeStr = changeTextChange(regex: "\\d+", text: str, color: UIColor.red)
// let alertController = UIAlertController(title: "积分即将过期提醒",
// message: attributeStr.string, preferredStyle: .alert)
// let cancelAction = UIAlertAction(title: "兑换菜品", style: .cancel, handler: nil)
// let okAction = UIAlertAction(title: "暂不兑换", style: .default, handler: {
// action in
// print("点击了确定")
// })
// alertController.addAction(cancelAction)
// alertController.addAction(okAction)
// self.present(alertController, animated: true, completion: nil)

//根据正则表达式改变文字颜色


func changeTextChange(regex: String, text: String, color: UIColor) -> NSMutableAttributedString {


let attributeString = NSMutableAttributedString(string: text)


do {


let regexExpression = try NSRegularExpression(pattern: regex, options: NSRegularExpression.Options())


let result = regexExpression.matches(in: text, options: NSRegularExpression.MatchingOptions(), range: NSMakeRange(0, text.characters.count))


for item in result {


attributeString.addAttribute(NSAttributedStringKey.foregroundColor, value: color, range: item.range)


}


} catch {


print("Failed with error: \(error)")


}


return attributeString


}

用NSAttributedstring改变属性了的属性字符串,如果再转换成String,之前的属性就没有了,是否可以直接把NSAttributedstring的属性字符串直接添加到AlertViewController中替换掉要改变字体颜色的string呢?

网上说是有解决办法的,但是没找到解决办法,有知道记得告诉思思哈。

http://www.maccocoa.com/forum/archive/index.php/t-130.html

于是只有自定义AlertView,这样怎么都能实现了。

//
// CustomAlertView.swift
// HaidilaoPad
//
// Created by 彭思 on 2018/5/3.
// Copyright © 2018年 HongHuoTai. All rights reserved.
// import UIKit let AlertWidth: CGFloat =
let AlertHeight: CGFloat =
let AlertPadding: CGFloat =
let MenuHeight: CGFloat = enum ButtonType {
case button_OK
case button_CANCEL
case button_OTHER
} class AlertItem: NSObject {
var title: String?
var type: ButtonType?
var tag: NSInteger?
var action: ((_ item:AlertItem) -> Void)?
} class CustomAlertView: UIView { // MARK: - Lazy
lazy var coverView: UIView = {
let coverView = UIView(frame: self.topView().bounds)
coverView.backgroundColor = UIColor.black
coverView.alpha =
coverView.autoresizingMask = UIViewAutoresizing.flexibleHeight
return coverView
}()
lazy var alertView: UIView = {
let alertView = UIView(frame: CGRect(x: , y: , width: AlertWidth, height: AlertHeight))
alertView.center = CGPoint(x: self.frame.size.width/, y: self.frame.size.height/)
alertView.layer.masksToBounds = true
alertView.layer.cornerRadius =
alertView.backgroundColor = UIColor.white
return alertView
}()
lazy var titleLabel: UILabel = {
let titleLabel = UILabel()
titleLabel.font = UIFont.boldSystemFont(ofSize: )
titleLabel.textColor = UIColor.black
titleLabel.textAlignment = NSTextAlignment.center
titleLabel.numberOfLines =
titleLabel.text = self.title
titleLabel.lineBreakMode = NSLineBreakMode.byCharWrapping
return titleLabel
}()
lazy var topLineView: UIView = {
let topLineView = UIView()
topLineView.backgroundColor = UIColor.lightGray
return topLineView
}()
lazy var messageLabel: UILabel = {
let messageLabel = UILabel()
messageLabel.font = UIFont.systemFont(ofSize: )
messageLabel.textAlignment = .center
messageLabel.numberOfLines =
messageLabel.textAlignment = NSTextAlignment.center
messageLabel.lineBreakMode = NSLineBreakMode.byCharWrapping
return messageLabel
}() var buttonScrollView: UIScrollView?
var contentScrollView: UIScrollView? var items: NSMutableArray?
var title: String?
var message: String? var buttonWidth: CGFloat?
var contentView: UIView? override init(frame: CGRect) {
super.init(frame: frame)
} // 便利构造函数
convenience init(title:String, message:String, messageColor:UIColor?) { // 计算frame
var screenWidth = UIScreen.main.bounds.size.width
var screenHeight = UIScreen.main.bounds.size.height
// On iOS7, screen width and height doesn't automatically follow orientation
if floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1 {
let interfaceOrientation = UIApplication.shared.statusBarOrientation
if UIInterfaceOrientationIsLandscape(interfaceOrientation) {
let tmp = screenWidth
screenWidth = screenHeight
screenHeight = tmp
}
}
let rect = CGRect(x: , y: , width: screenWidth, height: screenHeight)
self.init(frame: rect)
self.items = NSMutableArray()
self.title = title
self.message = message // 设置views
self.setupSubViews(messageColor)
} required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
} // MARK: - Setup UI func setupSubViews(_ color:UIColor?) { self.topView().addSubview(self.coverView)
self.addSubview(self.alertView)
// 设置title
let labelHeight = self.heightOfRow(self.title!, font: , width: AlertWidth - * AlertPadding)
titleLabel.frame = CGRect(x: AlertPadding, y: AlertPadding, width: AlertWidth - * AlertPadding, height: labelHeight)
self.alertView.addSubview(self.titleLabel)
topLineView.frame = CGRect(x: , y: self.titleLabel.frame.origin.y + self.titleLabel.frame.size.height + , width: AlertWidth, height: 0.5)
self.alertView.addSubview(self.topLineView) // 设置message
let messageHeight = self.heightOfRow(self.message!, font: , width: AlertWidth - * AlertPadding)
messageLabel.frame = CGRect(x: AlertPadding, y: self.topLineView.frame.origin.y + self.topLineView.frame.size.height + , width: AlertWidth - * AlertPadding, height: messageHeight + * AlertPadding)
self.alertView.addSubview(self.messageLabel) let mesColor:UIColor = color ?? UIColor.black
messageLabel.textColor = mesColor
let attributeStr = changeTextChange(regex: "\\d+", text: self.message!, color: UIColor.red)
self.messageLabel.attributedText = attributeStr
self.alertView.addSubview(self.messageLabel) self.contentScrollView = UIScrollView(frame: CGRect.zero)
self.alertView.addSubview(self.contentScrollView!) UIDevice.current.beginGeneratingDeviceOrientationNotifications()
NotificationCenter.default.addObserver(self, selector: #selector(CustomAlertView.deviceOrientationDidChange(_:)), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
} // dealloc
deinit {
UIDevice.current.endGeneratingDeviceOrientationNotifications()
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
} // override func override func layoutSubviews() {
self.buttonScrollView?.frame = CGRect(x: , y: self.alertView.frame.size.height-MenuHeight,width: self.alertView.frame.size.width, height: MenuHeight);
self.contentScrollView?.frame = CGRect(x: , y: self.titleLabel.frame.origin.y + self.titleLabel.frame.size.height, width: self.alertView.frame.size.width, height: self.alertView.frame.size.height - MenuHeight);
self.contentView?.frame = CGRect(x: ,y: ,width: self.contentView!.frame.size.width, height: self.contentView!.frame.size.height);
if self.contentView != nil {
self.contentScrollView?.contentSize = self.contentView!.frame.size;
} } override func willMove(toSuperview newSuperview: UIView?) {
self.addButtonItem()
if self.contentView != nil {
self.contentScrollView?.addSubview(self.contentView!)
}
self.reLayout()
} // show and dismiss
func topView() -> UIView {
let window = UIApplication.shared.keyWindow
return (window?.subviews[])!
} func show() {
UIView.animate(withDuration: 0.5, animations: { () -> Void in
self.coverView.alpha = 0.5
}, completion: { (finished) -> Void in })
self.topView().addSubview(self)
self.showAnimation()
} //------Preoperties------
func addButtonWithTitle(_ title:String) -> NSInteger {
let item = AlertItem()
item.title = title
item.action = {(ite:AlertItem)->Void in
print("no action")
}
item.type = ButtonType.button_OK
self.items?.add(item)
return (self.items?.index(of: title))!
} func addButton(_ type:ButtonType, title:String, handler:@escaping ((_ item:AlertItem) -> Void)) {
let item = AlertItem()
item.title = title
item.action = handler
item.type = type
self.items?.add(item)
item.tag = self.items?.index(of: item)
} func addButtonItem() {
self.buttonScrollView = UIScrollView(frame: CGRect(x: , y: self.alertView.frame.size.height - MenuHeight,width: AlertWidth, height: MenuHeight))
self.buttonScrollView?.bounces = false
self.buttonScrollView?.showsHorizontalScrollIndicator = false
self.buttonScrollView?.showsVerticalScrollIndicator = false
let width:CGFloat
if (self.buttonWidth != nil) {
width = self.buttonWidth!
let a = CGFloat((self.items?.count)!)
self.buttonScrollView?.contentSize = CGSize(width: a * width, height: MenuHeight)
} else {
width = (self.alertView.frame.size.width) / CGFloat((self.items?.count)!)
} self.items?.enumerateObjects({ (item, idx, stop) in
let button = UIButton(type: UIButtonType.system)
button.frame = CGRect(x: CGFloat(idx) * width, y: , width: width, height: MenuHeight)
button.backgroundColor = UIColor.white
button.layer.shadowColor = UIColor.gray.cgColor
button.layer.shadowRadius = 0.5
button.layer.shadowOpacity =
button.layer.shadowOffset = CGSize.zero
button.layer.masksToBounds = false
button.tag = + idx
button.setTitleColor(UIColor.darkGray, for: .normal) let ite = item as! AlertItem button.setTitle(ite.title, for: UIControlState())
button.setTitle(ite.title, for: UIControlState.selected)
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: (button.titleLabel?.font.pointSize)!) button.addTarget(self, action: #selector(CustomAlertView.buttonTouched(_:)), for: UIControlEvents.touchUpInside)
self.buttonScrollView?.addSubview(button) // 按钮边框
if idx != (self.items?.count)! - {
let seprateLineVer = UIView(frame: CGRect(x: width - , y: , width: 0.5, height: MenuHeight))
seprateLineVer.backgroundColor = UIColor.lightGray
button.addSubview(seprateLineVer)
} let seprateLineHor = UIView(frame: CGRect(x: , y: , width: self.buttonScrollView!.frame.size.width, height: 0.5))
seprateLineHor.backgroundColor = UIColor.lightGray
self.buttonScrollView?.addSubview(seprateLineHor)
})
self.alertView.addSubview(self.buttonScrollView!)
} @objc func buttonTouched(_ button:UIButton) {
let item:AlertItem = self.items![button.tag - ] as! AlertItem
if (item.action != nil) {
item.action!(item)
}
self.dismiss()
} func reLayout() {
var plus:CGFloat
if self.contentView != nil {
plus = (self.contentView!.frame.size.height) - ((self.alertView.frame.size.height) - MenuHeight)
} else {
plus = (self.messageLabel.frame.origin.y) + (self.messageLabel.frame.size.height) - ((self.alertView.frame.size.height) - MenuHeight)
}
plus = max(, plus)
let height = min(self.screenBounds().size.height - MenuHeight, (self.alertView.frame.size.height) + plus) self.alertView.frame = CGRect(x: self.alertView.frame.origin.x, y: self.alertView.frame.origin.y, width: AlertWidth, height: height)
self.alertView.center = self.center
self.setNeedsDisplay()
self.setNeedsLayout()
} func dismiss() {
self.hideAnimation()
} // MARK: - showAnimation
func showAnimation() {
let popAnimation = CAKeyframeAnimation(keyPath: "transform")
popAnimation.duration = 0.4
popAnimation.values = [
NSValue.init(caTransform3D: CATransform3DMakeScale(0.01, 0.01, 1.0)),
NSValue.init(caTransform3D: CATransform3DMakeScale(1.1, 1.1, 1.0)),
NSValue.init(caTransform3D: CATransform3DMakeScale(0.9, 0.9, 1.0)),
NSValue.init(caTransform3D: CATransform3DIdentity)
]
popAnimation.keyTimes = [0.2, 0.5, 0.75, 1.0]
popAnimation.timingFunctions = [
CAMediaTimingFunction.init(name: kCAMediaTimingFunctionEaseInEaseOut),
CAMediaTimingFunction.init(name: kCAMediaTimingFunctionEaseInEaseOut),
CAMediaTimingFunction.init(name: kCAMediaTimingFunctionEaseInEaseOut)
]
self.alertView.layer.add(popAnimation, forKey: nil)
} func hideAnimation() {
UIView.animate(withDuration: 0.4, animations: { () -> Void in
self.coverView.alpha = 0.0
self.alertView.alpha = 0.0
}, completion: { (finished) -> Void in
self.removeFromSuperview()
})
} // handle device orientation changes
@objc func deviceOrientationDidChange(_ notification:Notification) {
self.frame = self.screenBounds()
UIView.animate(withDuration: 0.2, delay: 0.0, options: UIViewAnimationOptions(), animations: { () -> Void in
self.reLayout()
}) { (finished) -> Void in }
} //------Tools-------
// 计算frame
func screenBounds() -> CGRect {
var screenWidth = UIScreen.main.bounds.size.width
var screenHeight = UIScreen.main.bounds.size.height
// On iOS7, screen width and height doesn't automatically follow orientation
if floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1 {
let interfaceOrientation = UIApplication.shared.statusBarOrientation
if UIInterfaceOrientationIsLandscape(interfaceOrientation) {
let tmp = screenWidth
screenWidth = screenHeight
screenHeight = tmp
}
}
return CGRect(x: , y: , width: screenWidth, height: screenHeight)
} // 计算字符串高度
func heightOfRow(_ text:String, font:CGFloat, width:CGFloat) -> CGFloat {
let size:CGSize = text.boundingRect(with: CGSize(width: width, height: ), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font : UIFont.systemFont(ofSize: font)], context: nil).size
return size.height;
} //根据正则表达式改变文字颜色
func changeTextChange(regex: String, text: String, color: UIColor) -> NSMutableAttributedString {
let attributeString = NSMutableAttributedString(string: text)
do {
let regexExpression = try NSRegularExpression(pattern: regex, options: NSRegularExpression.Options())
let result = regexExpression.matches(in: text, options: NSRegularExpression.MatchingOptions(), range: NSMakeRange(, text.characters.count))
for item in result {
attributeString.addAttribute(NSAttributedStringKey.foregroundColor, value: color, range: item.range)
}
} catch {
print("Failed with error: \(error)")
}
return attributeString
}
}

 实现效果如下:

最新文章

  1. 通过反汇编理解函数调用机制(x86和ARM)
  2. 04、生成 HTMLTestRunner 测试报告
  3. [Excel] C#DataToExcel帮助类 (转载)
  4. Windows Service的安装卸载 和 Service控制
  5. Redis集群方案
  6. linux面试题集锦2《转》
  7. mui 页面间传值得2种方式
  8. 【Android Developers Training】 75. 使用NSD
  9. express学习
  10. Redis 实践1- redis介绍和安装
  11. vue小白快速入门
  12. 39.Odoo产品分析 (四) – 工具板块(8) – 生产力(1)
  13. 浅尝flutter中的http请求
  14. Linux命令:history
  15. GlusterFS PERFORMANCE TUNING
  16. [代码审计]某开源商城前台getshell
  17. win32多线程(三) 死锁
  18. C++_函数4-函数重载与函数模板
  19. 【mysql优化】大数据量分页优化
  20. JavaScript 对大小写敏感。

热门文章

  1. jquery 表单对象属性筛选选择器
  2. AbsInt — 确保代码安全的性能/资源分析工具套件
  3. java调用c++库
  4. 在命令行中执行kms命令激活Microsoft Office 2010
  5. 项目Alpha冲刺(团队)-第八天冲刺
  6. 聚类------KNN
  7. 用junit Test Suite来组合测试
  8. 2019.12.10 定义数组及java内存划分
  9. javascript 百度地图无秘钥(appkey)创建marker标记地图
  10. 第12组 Alpha冲刺(4/6)