-
以协议的方式,把方法写在协议中,调用部分实现这个协议并重写回调函数,这和Android的接口基本一致。
以函数作为参数类型的方式,调用部分通过传递函数类型参数至PopupWindow,而在调用部分以闭包或者尾随闭包的形式添加交互功能。
两种方式一般都可以随性,但第一种适合交互函数比较多的时候。第二种适合于同一调用类中出现多个地方不同调用,一些设置属性也不相同。
我们这里选择第一种,以协议的方式:
protocol PopupWindowDelegate {
func attach()
func detach()
func rename()
func delete()
func control()
}
这里具体函数完全不用管它,是从项目中截取的。
当然我们需要在PopupWindow中定义一个该协议类型的变量:
public var delegate: PopupWindowDelegate?
通过协议对象来调用交互函数:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let row = indexPath.row
switch itemsString[row] {
case "attach":
delegate?.attach()
cancel()
case "detach":
delegate?.detach()
cancel()
case "rename":
delegate?.rename()
cancel()
case "delete":
delegate?.delete()
cancel()
case "control":
delegate?.control()
cancel()
default:
break
}
}
这是UICollectionView item的选择函数,这里不多说。注意协议对象对其函数的调用,这里只相当于一种绑定。真正的调用在调用地方对协议对象的赋值。
除了这些还有一个最重要的东西,就是声明对于PopupWindow对象的一个强引用,如果这个不存在,交互功能依然不可用。原因是为了防止当前对象被回收掉,有了强引用,只有强引用置空时,对象才能被回收掉。
var strongSelf: PopupWindow?
引用赋值即可以放在弹出函数create()中,也可以放在viewDidLoad()中,执行顺序是弹出函数create()在前。这里放在viewDidLoad()中的:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.view.backgroundColor = UIColor.init(white: 0, alpha: 0)
let gesture = UITapGestureRecognizer(target: self, action: #selector(cancel))
gesture.delegate = self
self.dismissView.addGestureRecognizer(gesture)
self.collectionView.delegate = self
self.collectionView.dataSource = self
strongSelf = self
}
里面对于UICollectionView的操作可以忽略,dismissView是取消PopupView的按钮,当然并没有用UIButton,用的是UIView,所以要手动添加点击事件。
取消










