iOS Swift 写一个弹框

前言:

写了一个Swift版本的弹框。

代码地址:

代码地址:https://gitee.com/yuency/Autolayout
示例代码类名 【PopViewController】【OutageSubscribePopView】

弹框效果:


弹框.png

上代码!

OutageSubscribePopView.swift

import UIKit

typealias BlockClickSubscribe = (_ text: String) -> Void
typealias BlockClickClose = () -> Void

class OutageSubscribePopView: UIView {
    
    static let buttonHeight: CGFloat = 52
    
    var clickSubscribe: BlockClickSubscribe?
    var clickClose: BlockClickClose?
    
    lazy var tapGesture = UITapGestureRecognizer()
    
    lazy var grayMaskView: UIView = {
        let grayMaskView = UIView()
        grayMaskView.backgroundColor = UIColor.black.withAlphaComponent(0.2)
        grayMaskView.addGestureRecognizer(tapGesture)
        return grayMaskView
    }()
    
    lazy var backView: UIView = {
        let backView = UIView()
        backView.backgroundColor = UIColor.white
        backView.layer.cornerRadius = 12
        return backView
    }()
    
    private lazy var shadowBar: OutageShadowBar = {
        let shadowBar = OutageShadowBar()
        return shadowBar
    }()
    
    lazy var subscribeButton: UIButton = {
        let subscribeButton = UIButton()
        subscribeButton.setTitle("这是我的标题", for: .normal)
        subscribeButton.setTitleColor(UIColor.blue, for: .normal)
        subscribeButton.titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: .medium)
        return subscribeButton
    }()
    
    lazy var cancelButton: UIButton = {
        let cancelButton = UIButton()
        cancelButton.setTitle("取消", for: .normal)
        cancelButton.setTitleColor(UIColor.blue, for: .normal)
        cancelButton.titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: .regular)
        cancelButton.backgroundColor = UIColor.purple.withAlphaComponent(0.1)
        return cancelButton
    }()
    
    lazy var topRightCloseButton: UIButton = {
        let topRightCloseButton = UIButton()
        topRightCloseButton.backgroundColor = UIColor.green
        topRightCloseButton.setTitle("关闭", for: .normal)
        topRightCloseButton.setTitleColor(UIColor.red, for: .normal)
        return topRightCloseButton
    }()
    
    lazy var contentGrayView: UIView = {
        let contentGrayView = UIView()
        contentGrayView.layer.cornerRadius = 10
        contentGrayView.backgroundColor = UIColor.yellow
        return contentGrayView
    }()
    
    lazy var contentLabel: UILabel = {
        let contentLabel = UILabel()
        contentLabel.numberOfLines = 0
        return contentLabel
    }()
    
    lazy var titleLabel: UILabel = {
        let titleLabel = UILabel()
        titleLabel.font = UIFont.systemFont(ofSize: 14, weight: .regular)
        titleLabel.textColor = UIColor.black
        titleLabel.text = "我停电了"
        return titleLabel
    }()
    
    deinit {
        print("\((#file as NSString).lastPathComponent) dealloc")
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setUI()
        setConstraints()
        setBindings()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // 这段代码需要抽取出来, 左晨公用的
    static func getAttributeString(firstText: String) -> NSMutableAttributedString {
        let attributeString = NSMutableAttributedString(string: firstText)
        let paragraph = NSMutableParagraphStyle()
        paragraph.alignment = .natural
        let multipleAttributes: [NSAttributedString.Key: Any] = [
            .paragraphStyle: paragraph,
            .font: UIFont.systemFont(ofSize: 16, weight: .regular),
            .foregroundColor: UIColor.black]
        attributeString.addAttributes(multipleAttributes, range: NSRange(location: 0, length: firstText.count))
        
        let indexArray: [Int] = firstText.indicesOf(string: "\"")
        let indexCount = indexArray.count
        if indexCount % 2 == 0 {
            for i in stride(from: 0, to: indexArray.count - 1, by: 2) {
                attributeString.addAttribute(.font, value: UIFont.systemFont(ofSize: 16, weight: .bold), range: NSRange(location: indexArray[i] + 1, length: indexArray[i+1] - indexArray[i] - 1))
                attributeString.addAttribute(.foregroundColor, value: UIColor.red, range: NSRange(location: indexArray[i] + 1, length: indexArray[i+1] - indexArray[i] - 1))
            }
        }
        return attributeString
    }
    
    static func showView(name: String, age: String, time: String, clickSubscribe: @escaping BlockClickSubscribe, clickClose: @escaping BlockClickClose) {
        let subscribePopView = OutageSubscribePopView()
        subscribePopView.clickSubscribe = clickSubscribe
        subscribePopView.clickClose = clickClose
        
        let formatString = String(format: "这是内容,内容里面有文字样式是\"被引用加粗的文字\"这个就是重点啊,然后还有3个占位符%@AAA%@BBB%@CCC", name, age, time)
        subscribePopView.contentLabel.attributedText = OutageSubscribePopView.getAttributeString(firstText: formatString)
        
        let window = UIApplication.shared.windows.last
        window?.addSubview(subscribePopView)
        subscribePopView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        window?.layoutIfNeeded()
        subscribePopView.alpha = 0
        UIView.animate(withDuration: 0.1) {
            subscribePopView.alpha = 1
        } completion: { _ in
            UIView.animate(withDuration: 0.1, animations: {
                subscribePopView.backView.snp.updateConstraints { make in
                    // for layout animation in view presenting from bottom, content height depend on subviews
                    make.top.equalTo(subscribePopView.snp.bottom).offset(-subscribePopView.backView.frame.height)
                }
                subscribePopView.layoutIfNeeded()
            }, completion: nil)
        }
    }
    
    func setUI() {
        addSubview(grayMaskView)
        addSubview(backView)
        backView.addSubview(cancelButton)
        backView.addSubview(shadowBar)
        backView.addSubview(subscribeButton)
        backView.addSubview(topRightCloseButton)
        backView.addSubview(contentGrayView)
        contentGrayView.addSubview(contentLabel)
        backView.addSubview(titleLabel)
    }
    
    func setConstraints() {
        grayMaskView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        backView.snp.makeConstraints { make in
            // for layout animation in view presenting from bottom, content height depend on subviews
            make.top.equalTo(self.snp.bottom).offset(0)
            make.left.right.equalToSuperview()
        }
        
        var safeBottomHeight: CGFloat = 0
        if #available(iOS 11.0, *) {
            safeBottomHeight = UIApplication.shared.windows.last?.safeAreaInsets.bottom ?? 0
        } else {
            // Fallback on earlier versions
        }
        cancelButton.snp.makeConstraints { make in
            make.bottom.equalTo(-safeBottomHeight-20)
            make.left.equalTo(20)
            make.right.equalTo(-20)
            make.height.equalTo(OutageSubscribePopView.buttonHeight)
        }
        shadowBar.snp.makeConstraints { make in
            make.bottom.equalTo(cancelButton.snp.top).offset(-30)
            make.left.equalTo(20)
            make.right.equalTo(-20)
            make.height.equalTo(OutageSubscribePopView.buttonHeight)
        }
        subscribeButton.snp.makeConstraints { make in
            make.edges.equalTo(shadowBar)
        }
        contentGrayView.snp.makeConstraints { make in
            make.left.equalTo(20)
            make.right.equalTo(-20)
            make.bottom.equalTo(shadowBar.snp.top).offset(-20)
        }
        contentLabel.snp.makeConstraints { make in
            make.edges.equalTo(UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10))
        }
        titleLabel.snp.makeConstraints { make in
            make.left.equalTo(20)
            make.right.equalTo(topRightCloseButton.snp.left).offset(-13)
            make.bottom.equalTo(contentGrayView.snp.top).offset(-20)
            make.top.equalTo(20)
        }
        topRightCloseButton.snp.makeConstraints { make in
            make.centerY.equalTo(titleLabel)
            make.right.equalToSuperview().offset(-13)
            make.height.width.equalTo(44)
        }
    }
    
    func setBindings() {
        topRightCloseButton.addTarget(self, action: #selector(action_close), for: .touchUpInside);
        cancelButton.addTarget(self, action: #selector(action_close), for: .touchUpInside);
        tapGesture.addTarget(self, action: #selector(action_close))
        subscribeButton.addTarget(self, action: #selector(action_subscribe), for: .touchUpInside);
    }
    
    @objc func action_close() {
        if let clickClose = clickClose {
            clickClose()
        }
        disMissView()
    }
    
    @objc func action_subscribe() {
        if let clickSubscribe = clickSubscribe {
            clickSubscribe("9789697979865469789")
        }
        disMissView()
    }
    
    func disMissView() {
        clickSubscribe = nil
        clickClose = nil
        removeFromSuperview()
    }
}

class OutageShadowBar: UIView {
    let cornerRadius:CGFloat = OutageSubscribePopView.buttonHeight * 0.5
    override var bounds: CGRect {
        didSet {
            setupShadow()
        }
    }
    private func setupShadow() {
        backgroundColor = UIColor.white
        layer.cornerRadius = cornerRadius
        layer.borderWidth = 1
        layer.borderColor = UIColor.white.cgColor
        layer.shadowColor = UIColor.black.cgColor
        layer.shadowOffset = CGSize(width: 0, height: 2)
        layer.shadowOpacity = 0.1
        layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).cgPath
    }
}

public extension String {
    func indicesOf(string: String) -> [Int] {
        var indices = [Int]()
        var searchStartIndex = self.startIndex
        while searchStartIndex < self.endIndex, let range = self.range(of: string, range: searchStartIndex..

调用:

import UIKit

class PopViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
    }
    
    @IBAction func action_1(_ sender: UIButton) {
        OutageSubscribePopView.showView(name: "我是张三", age: "18岁了", time: "就在今年") { text in
            print("收到了东西 \(text)")
        } clickClose: {
            print("点击关闭")
        }
    }
}

结语

暂无

你可能感兴趣的:(iOS Swift 写一个弹框)