Swift-遮盖(可以自定义尺寸/子控件)
2018-08-08 本文已影响0人
SK丿希望
图片展示


简单使用
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释放")
}
}
缺点
如果需要点击事件必须添加按钮才能实现...