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

2018-08-08  本文已影响0人  SK丿希望

图片展示

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

缺点

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

上一篇 下一篇

猜你喜欢

热点阅读