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

第一反应就用系统的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
}
}

 实现效果如下:

Swift自定义AlertView的更多相关文章

  1. [IOS]swift自定义uicollectionviewcell

    刚刚接触swift以及ios,不是很理解有的逻辑,导致某些问题.这里分享一下swift自定义uicollectionviewcell 首先我的viewcontroller不是直接继承uicollect ...

  2. iOS 第三方自定义Alertview项目MBProcessHud中的重要代码分析

    做ios,弹出一个自定义的alertview挺常见的.ios7以前,我们可以对系统的UIAlertView进行一点操作,实现一点简单的定制,但是ios7不再允许我们这样做了.因此,我们需要自己创建一个 ...

  3. Swift 自定义打印方法

    Swift 自定义打印方法 代码如下 // MARK:- 自定义打印方法 func MLLog<T>(_ message : T, file : String = #file, funcN ...

  4. 兼容iOs7的自定义alertView

    转载请注明出处. 升级到ios7后,旧项目中使用的继承UIAlertView的自定义alertview无法正常显示了,无奈只好换思路去实现,改成从当前keywindow下创建要显示的alertview ...

  5. 自定义AlertView的方法和改变Alert的弹出位置以及其宽度

    此方法在IOS7中不适合 一.自定义AlertView 1.首先新建一个OC类继承与AlertView. 2.然后再.m中添加方法 - (void)layoutSubviews 可以再这个方法里边改变 ...

  6. 自定义AlertView(Swift)

    MyAlertView.swift // Pop Up Styles enum MyAlertViewStyle: Int { case success case error case notice ...

  7. swift 自定义弹框

    // //  ViewController.swift //  animationAlert // //  Created by su on 15/12/9. //  Copyright © 2015 ...

  8. swift 自定义图片轮播视图

    Swift封装图片轮播视图: import UIKit class XHAdLoopView: UIView { private var pageControl : UIPageControl? pr ...

  9. Swift 自定义Subscript

    Swift可以方便给自定义类加下标,其中参数和返回值可以在类里定义为任意类型: subscript(parameters) -> ReturnType { get { //return some ...

随机推荐

  1. PHP中的分支及循环语句

    这次实践的都是PHP7的语法. 感觉是以前的5差别不是那么大,只是希望越来越快吧. <?php $looking = isset($_GET['title']) || isset($_GET[' ...

  2. Alpha冲刺随笔八:第八天

    课程名称:软件工程1916|W(福州大学) 作业要求:项目Alpha冲刺(十天冲刺) 团队名称:葫芦娃队 作业目标:在十天冲刺里对每天的任务进行总结. 随笔汇总:https://www.cnblogs ...

  3. javascript Object and new object() object --构造函数

  4. 域渗透:SPN(ServicePrincipal Names)的利用

    SPN 简介:服务主体名称(SPN:ServicePrincipal Names)是服务实例(可以理解为一个服务,比如 HTTP.MSSQL)的唯一标识符.Kerberos 身份验证使用 SPN 将服 ...

  5. Java LinkedList add vs push

    Java LinkedList add 是加在list尾部. LinkedList push 施加在list头部. 等同于addFirst.

  6. java 值传递、引用传递

    class Demo02 { public static void main(String[] args) { int a=1; get(a);//值传递 System.out.println(a); ...

  7. 中断点异常 STATUS_BREAKPOINT(0x80000003)

    简介 STATUS_BREAKPOINT,值为0x80000003,称为中断指令异常,表示在系统未附加内核调试器时遇到断点或断言. 触发条件 通常中断指令异常可以在以下条件下触发: 硬代码中断请求,如 ...

  8. nexus 3.17.0 简单试用

    老样子,使用docker-compose 运行 环境准备 docker-compose 文件 version: "3" services: nexus: image: sonaty ...

  9. MQTT 遗嘱使用

    大部分人应该有这个需求: 我想让我的APP或者上位机或者网页一登录的时候获取设备的状态   在线还是离线 设备端只需要这样设置 注意:MQTT本身有遗嘱设置 所以大家可以设置遗嘱 ,注意哈,发布的主题 ...

  10. PDE工具箱的简单使用

    转载自Here matlab的PDE工具箱的简单使用 问题选择 边界条件选择 菜单按钮和简单使用 命令行输入pdetool,打开GUI编辑界面如下: 注意到工具栏上,就是我们要用到的,从左到右依次使用 ...