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

第一反应就用系统的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. Python开发AI应用-国际象棋应用

    AI 部分总述     AI在做出决策前经过三个不同的步骤.首先,他找到所有规则允许的棋步(通常在开局时会有20-30种,随后会降低到几种).其次,它生成一个棋步树用来随后决定最佳决策.虽然树的大小随 ...

  2. Yarn (转自之乎者也)

    作者:青俞链接:https://www.zhihu.com/question/34016617/answer/57822812来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出 ...

  3. insmod: ERROR: could not insert module dm-snapshot.ko: Unknown symbol in module

    下面方法成功的前提是你的mod和你的操作系统版本是匹配的,也就是说你的mod之前成功过.说个多余的提示,mod在/lib/modules目录里面 insmod: ERROR: could not in ...

  4. GSM/GPRS模块 AT指令集C语言编程——基于有方M660+和MSP430单片机

    GSM/GPRS芯片是手机中负责收发短信.拨打电话以及访问GPRS网络的核心器件.有方M660+为深圳有方公司生产的一款超小封装的GSM/GPRS工业无线模块,可以提供高品质的语音.短信.数据业务等功 ...

  5. gin+redis

    var RedisDefaultPool *redis.Pool func newPool(addr string) *redis.Pool { return &redis.Pool{ Max ...

  6. vue基本使用及脚手架使用

    一.基本使用: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...

  7. learning scala akka ask_pattern

    package com.example import akka.actor._ import akka.util.Timeout object Tutorial_03_Ask_Pattern exte ...

  8. Linux 系统管理——文件系统与LVM、磁盘配额实例

    1.为主机增加80G SCSI 接口硬盘 2.划分三个各20G的主分区 3.将三个主分区转换为物理卷(pvcreate),扫描系统中的物理卷 4.使用两个物理卷创建卷组,名字为myvg,查看卷组大小 ...

  9. 深入浅出的Java网络通信

    已经发表个人公众号 代码展示 package two; import java.io.BufferedReader; import java.io.InputStreamReader; import ...

  10. 刷题之给定一个整数数组 nums 和一个目标值 taget,请你在该数组中找出和为目标值的那 两个 整数

    今天下午,看了一会github,想刷个题呢,就翻出来了刷点题提高自己的实际中的解决问题的能力,在面试的过程中,我们发现,其实很多时候,面试官 给我们的题,其实也是有一定的随机性的,所以我们要多刷更多的 ...