IOS控件列---仿Android的Toast提示信息

来源:互联网 发布:广电网络资费 编辑:程序博客网 时间:2024/06/07 02:10
本案例设计思路没什么难的地方,只要掌握了CAShapeLayer +

UIBezierPath


效果图如下:



与基本动画 的使用,设计出来完全没问题,直接奉送代码:


import UIKit/// wegt结构体来控制提示文本的信息struct TextTipsInfo {        var position : CGRect        var color : UIColor        var font : UIFont        var text : String        var fontSize : CGFloat}/// 类似安卓Toast对象class ToastView: UIView {            lazy var textLayer : (TextTipsInfo) ->VerticalTextLayer = {(textInfo : TextTipsInfo) -> VerticalTextLayer in            let tmpLayer : VerticalTextLayer = VerticalTextLayer()        tmpLayer.frame = CGRect.init(x: textInfo.position.origin.x,                                     y: textInfo.position.origin.y,                                 width: textInfo.position.size.width,                                height: textInfo.position.size.height)                tmpLayer.foregroundColor = textInfo.color.cgColor;        tmpLayer.alignmentMode = kCAAlignmentCenter;        tmpLayer.isWrapped = true;        tmpLayer.font = textInfo.font        tmpLayer.fontSize = textInfo.fontSize        tmpLayer.string = textInfo.text                tmpLayer.contentsScale = UIScreen.main.scale;                return tmpLayer        }        lazy var circleLayer : CAShapeLayer = CAShapeLayer()        lazy var successLayer : CAShapeLayer = CAShapeLayer()        lazy var failLayer : CAShapeLayer = CAShapeLayer()        lazy var centerPos : CGPoint = {[unowned self]() -> CGPoint in                return CGPoint.init(x: self.frame.width / 2, y: self.frame.height / 2 - 10)    }()        lazy var animate : CABasicAnimation = {() -> CABasicAnimation in            let anim :  CABasicAnimation = CABasicAnimation.init(keyPath: "strokeEnd")        anim.duration = 0.7        anim.fromValue = 0.0        anim.toValue = 1.0        anim.fillMode = kCAFillModeForwards        anim.isRemovedOnCompletion = false        anim.delegate = self as CAAnimationDelegate        anim.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionLinear)                return anim            }()        lazy var bIsSuccess : Bool = false      //当使用动画模式时,是否播放成功动画        var bIsPureTypeModel : Bool = false     //是否为纯文本模式    override init(frame: CGRect) {        super.init(frame: frame)                    }            required init?(coder aDecoder: NSCoder) {        fatalError("init(coder:) has not been implemented")    }        func initAnimLayer(success : Bool) {                setCircleAttr(radius: 25, color: UIColor.green, strokWidth: 2.0)                guard success else {            setFailLayer(color: UIColor.green, strokWidth: 2.0)            return        }        setSuccessLayer(color: UIColor.green, strokWidth: 2.0)            }        func setCircleAttr(radius : CGFloat,color: UIColor,strokWidth : CGFloat){                let path : UIBezierPath = UIBezierPath.init()        path.addArc(withCenter: centerPos, radius: radius, startAngle: 0, endAngle: 3.1415926 * 2, clockwise: true)                circleLayer.lineWidth = strokWidth        circleLayer.path = path.cgPath        circleLayer.fillColor = UIColor.clear.cgColor        circleLayer.strokeColor = UIColor.green.cgColor        self.layer.addSublayer(circleLayer)    }        func setSuccessLayer(color : UIColor, strokWidth : CGFloat) {                        let successPath : UIBezierPath = UIBezierPath.init()        successPath.move(to: CGPoint.init(x: centerPos.x - 15, y: centerPos.y - 10))         //线的表达式为: y  = k *x + 5 其中 k = -1        successPath.addLine(to: CGPoint.init(x: centerPos.x - 2, y: centerPos.y + 3))                successPath.move(to:  CGPoint.init(x: centerPos.x - 2, y: centerPos.y + 3))          //线的表达式为: y  = -k * x  其中 k = -1        successPath.addLine(to:  CGPoint.init(x: centerPos.x + 15, y: centerPos.y - 15))                successLayer.lineWidth = strokWidth        successLayer.path = successPath.cgPath        successLayer.fillColor = UIColor.clear.cgColor        successLayer.strokeColor = color.cgColor        successLayer.strokeEnd = 0.0                self.layer.addSublayer(successLayer)            }        func setFailLayer(color : UIColor, strokWidth : CGFloat) {        let failPath : UIBezierPath = UIBezierPath.init()        failPath.move(to: CGPoint.init(x: centerPos.x - 12.5, y: centerPos.y - 12.5))         //线的表达式为: y  = k *x +        failPath.addLine(to: CGPoint.init(x: centerPos.x + 12.5, y: centerPos.y + 12.5))        //每一条线的斜率 = 1                failPath.move(to:  CGPoint.init(x: centerPos.x - 12.5, y: centerPos.y + 12.5))          //线的表达式为: y  = -k * x  其中 k = -1        failPath.addLine(to:  CGPoint.init(x: centerPos.x + 12.5, y: centerPos.y - 12.5))                failLayer.lineWidth = strokWidth        failLayer.path = failPath.cgPath        failLayer.fillColor = UIColor.clear.cgColor        failLayer.strokeColor = color.cgColor        failLayer.strokeEnd = 0.0        self.layer.addSublayer(failLayer)    }        func setTextLayer(textInfo : TextTipsInfo){                self.layer.addSublayer(textLayer(textInfo))    }        func toast(success : Bool,withTitle : String) {                self.bIsSuccess = success        initAnimLayer(success:success)        circleLayer.add(animate, forKey: "circleAnim")                setTextLayer(textInfo: TextTipsInfo.init(position: CGRect.init(x: centerPos.x - self.frame.width / 2,                                                                       y: self.frame.height - 30,                                                                       width: self.frame.width,                                                                       height: 30),                                                 color: UIColor.white,                                                 font: UIFont.systemFont(ofSize: 2),                                                 text: withTitle,                                                 fontSize: 14))            }            /// 只显示文本模式    ///    /// - Parameters:    ///   - text: 文本内容    ///   - color: 字体颜色    ///   - font: 字体信息    ///   - size: 画笔大小    func toastOnly(text : String) {                setTextLayer(textInfo: TextTipsInfo.init(position: CGRect.init(x: centerPos.x - self.frame.width / 2,                                                                       y: centerPos.y - 40 / 2,                                                                       width: self.frame.width,                                                                       height: 40),                                                 color: UIColor.white,                                                 font: UIFont.systemFont(ofSize: 2),                                                 text: text,                                                 fontSize: 14))                recycRes()    }            func recycRes() {                let time: TimeInterval = 1        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + time) {[unowned self] in                        UIView.animate(withDuration: 0.5, animations: {                                self.alpha = 0                            }, completion: {(true) -> Void in                                self.removeFromSuperview()            })        }    }    }extension ToastView : CAAnimationDelegate{    func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {                if(anim == circleLayer.animation(forKey: "circleAnim")){                    guard self.bIsSuccess else {                failLayer.add(animate, forKey: "failAnim")                return            }            successLayer.add(animate, forKey: "successAnim")                    }else if(anim == successLayer.animation(forKey: "successAnim") || anim == failLayer.animation(forKey: "failAnim")){                    recycRes()        }    }}/// 本类使用CATextLayer文本垂直居中class VerticalTextLayer : CATextLayer{        override func draw(in ctx: CGContext) {        let fontSize = self.fontSize        let height = self.bounds.size.height        let deltaY = (height-fontSize)/2 - fontSize/6                ctx.saveGState()        ctx.translateBy(x: 0.0, y: deltaY)        super.draw(in: ctx)        ctx.restoreGState()    }}

 在vc中测试方式:

override func viewDidLoad() {        initView()                let btnSuccessToast : UIButton = UIButton.init(frame: CGRect.init(x: 10, y: 400, width: 80, height: 40))        btnSuccessToast.backgroundColor = UIColor.gray        btnSuccessToast.tag = 41        btnSuccessToast.setTitle("加载成功", for: UIControlState.normal)        btnSuccessToast.addTarget(self, action: #selector(onClick), for: .touchUpInside)                self.view.addSubview(btnSuccessToast)                        let btnFailToast : UIButton = UIButton.init(frame: CGRect.init(x: 100, y: 400, width: 80, height: 40))        btnFailToast.backgroundColor = UIColor.gray        btnFailToast.tag = 42        btnFailToast.setTitle("加载失败", for: UIControlState.normal)        btnFailToast.addTarget(self, action: #selector(onClick), for: .touchUpInside)                self.view.addSubview(btnFailToast)                        let btnTextToast : UIButton = UIButton.init(frame: CGRect.init(x: 200, y: 400, width: 80, height: 40))        btnTextToast.backgroundColor = UIColor.gray        btnTextToast.tag = 43        btnTextToast.setTitle("文本模式", for: UIControlState.normal)        btnTextToast.addTarget(self, action: #selector(onClick), for: .touchUpInside)                self.view.addSubview(btnTextToast)                        let btncd : UIButton = UIButton.init(frame: CGRect.init(x: 290, y: 400, width: 80, height: 40))        btncd.backgroundColor = UIColor.gray        btncd.tag = 44        btncd.setTitle("倒计时动画", for: UIControlState.normal)        btncd.addTarget(self, action: #selector(onClick), for: .touchUpInside)                self.view.addSubview(btncd)            }        func onClick(button: UIButton){            switch button.tag {        case 41:                        //初始toast            let toast : ToastView = ToastView.init(frame: CGRect.init(x: getScreenSize().width / 2 - 50, y: getScreenSize().height / 2 - 50, width: 100, height: 100))            toast.backgroundColor = UIColor.gray            toast.toast(success: true,withTitle: "加载成功")                        self.view.addSubview(toast)                        break                    case 42:                        //初始toast            let toast : ToastView = ToastView.init(frame: CGRect.init(x: getScreenSize().width / 2 - 50, y: getScreenSize().height / 2 - 50, width: 100, height: 100))            toast.backgroundColor = UIColor.gray            toast.toast(success: false,withTitle: "加载失败")                        self.view.addSubview(toast)                        break;                    case 43 :                        //初始toast            let toast : ToastView = ToastView.init(frame: CGRect.init(x: getScreenSize().width / 2 - 150, y: getScreenSize().height / 2 - 150, width: 300, height: 300))            toast.backgroundColor = UIColor.gray            toast.toastOnly(text: "加载成功")                        self.view.addSubview(toast)                                                break;                    case 44:                        let countDowm : CountDownView = CountDownView.init(frame: CGRect.init(x: self.getScreenSize().width / 2 - 100, y: self.getScreenSize().height / 2 - 100, width: 100, height: 100))                        countDowm.setCircleAttr(radius: 25, color: UIColor.green, strokWidth: 2.0)                        countDowm.setTextAttr(initText: "10",                                  color: UIColor.black,                                  font: UIFont.systemFont(ofSize: 10),                                  size: CGSize.init(width: 50, height: 50))                        countDowm.countDownListener = self            countDowm.startCountDown(duration: 10)                        countDowm.backgroundColor = UIColor.gray                        self.view.addSubview(countDowm)                        break;                    default:            break;        }            }



原创粉丝点击