美文网首页
Swift-遮盖(可以自定义尺寸/子控件)

Swift-遮盖(可以自定义尺寸/子控件)

作者: SK丿希望 | 来源:发表于2018-08-08 11:27 被阅读0次

    图片展示

    image.png
    image.png

    简单使用

    import UIKit
    
    class ViewController: UIViewController {
        // 定义属性
        let cover = HWCoverView.init(frame: CGRect.init(x: 0, y: 120, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height-120))
        override func viewDidLoad() {
            super.viewDidLoad()
            // 成功代理
            cover.dataSource = self
            // 遮盖区域是否相应手势
            cover.isBlackRegionResponse = true
        }
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            // 显示遮盖
            cover.show()
        }
        // 在控制器即将移除遮盖
        override func viewWillDisappear(_ animated: Bool) {
            super.viewWillDisappear(animated)
            cover.removeCover()
        }
    }
    
    // 数据源方法
    extension ViewController : HWCoverDataSource {
        // 返回View
        func setupSubView(cover: HWCoverView) -> UIView {
            let view = subView.hw_loadViewFromNib() as! subView
            view.backgroundColor = UIColor.red
            view.buttonClickBlock = {
                cover.animationRemoveCover()
            }
            return view
        }
        // 返回Frame
        func setupSubViewRect(cover: HWCoverView) -> CGRect {
            return CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.width)
        }
    }
    

    实现原理

    import UIKit
    
    protocol HWCoverDataSource : NSObjectProtocol{
        /** 设置遮盖的子控件 */
        func setupSubView(cover : HWCoverView)->UIView
        /** 设置遮盖的子控件Frame */
        func setupSubViewRect(cover : HWCoverView)->CGRect
    }
    class HWCoverView: UIWindow {
        weak var dataSource : HWCoverDataSource?
        private weak var subView :UIView? // 注意这里对subView是弱引用
        /// 黑色区域是否响应事件
        var isBlackRegionResponse:Bool = false
        /// 黑色区域点击回调
        var tapClickBlock:(()->())?
        /// 用于记录真实Y
        private var realY : CGFloat = 0
        override init(frame: CGRect) {
            realY = frame.origin.y
            super.init(frame: CGRect.init(x: 0, y: UIScreen.main.bounds.size.height, width: frame.size.width, height: frame.size.height))
            self.backgroundColor = UIColor.clear
            self.windowLevel = UIWindowLevelAlert + 1
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        lazy var coverView : UIView = { // 懒加载
            let coverView = UIView.init()
            coverView.backgroundColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.2)
            let tap = UITapGestureRecognizer(target: self, action: #selector(self.tapOne(tap:)))
            //通过numberOfTouchesRequired属性设置触摸点数,比如设置2表示必须两个手指触摸时才会触发
            tap.numberOfTapsRequired = 1
            //通过numberOfTapsRequired属性设置点击次数,单击设置为1,双击设置为2
            tap.numberOfTouchesRequired = 1
            coverView.addGestureRecognizer(tap)
            return coverView
        }()
        func show(){
            if self.dataSource == nil { return }
            self.makeKeyAndVisible()
            self.addSubview(self.coverView)
            self.coverView.frame = self.bounds
            setSubView()
            UIView.animate(withDuration: 0.3) { [weak self] in
                self?.frame.origin.y = self?.realY ?? 0
            }
        }
        @objc private func tapOne(tap:UITapGestureRecognizer) { // 点击屏幕退出键盘
            let window = UIApplication.shared.keyWindow
            window?.endEditing(true)
            if isBlackRegionResponse {
                let tapPoint = tap.location(in: self.coverView)
                if  (self.subView?.frame.contains(tapPoint))! { return } // 判断当前点是否在subView上 在就直接return
                self.animationRemoveCover()
                if tapClickBlock == nil { return }
                tapClickBlock!()
            }
        }
        
        func removeCover() {
            self.subView?.removeFromSuperview()
            self.coverView.removeFromSuperview()
            self.resignKey()
        }
        func animationRemoveCover() {
            UIView.animate(withDuration: 0.3, animations: { [weak self] in
                self?.frame.origin.y = UIScreen.main.bounds.size.height
            }) { [weak self](tag) in
                self?.removeCover()
            }
        }
        private func setSubView() {
            weak var weakSelf = self // 弱引用
            // 将数据源返回的View添加到当前view上
            let subview = weakSelf!.dataSource?.setupSubView(cover: weakSelf!)
            weakSelf!.subView = subview
            subview?.frame = (weakSelf!.dataSource?.setupSubViewRect(cover: weakSelf!))!
            weakSelf!.coverView.addSubview(subview!)
        }
        deinit {
            print("HWCoverView释放")
        }
    }
    

    Dome

    缺点

    如果需要点击事件必须添加按钮才能实现...

    相关文章

      网友评论

          本文标题:Swift-遮盖(可以自定义尺寸/子控件)

          本文链接:https://www.haomeiwen.com/subject/yrutbftx.html