我有一个名为MyView的自定义UIView类和一个视图控制器。
当用户点击UIView上的按钮时,我想在视图控制器上调用一个函数。我试图通过授权实现这一目标
自定义UIClass
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);
// Restore state members from saved instance
mState = savedInstanceState.Boolean(STATE_VISIBILITY);
view.setVisibility(mState?View.VISIBLE:View.GONE);
}
我的视图控制器
@objc protocol MyViewDelegate{
optional func expandCollapse()
}
class MyView: UIView, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UICollectionViewDelegate{
weak var delegate:MyViewDelegate?
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
if self.subviews.count == 0 {
loadNib()
}
}
override init(frame:CGRect){
super.init(frame: frame)
loadNib()
}
func loadNib(){
let bundle = NSBundle(forClass: self.dynamicType)
let nib = UINib(nibName: "MyView", bundle: bundle)
let view = nib.instantiateWithOwner(self, options: nil)[0] as! MyView
view.frame = bounds
view.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
self.addSubview(view);
}
@IBAction func expandit(sender: AnyObject) {
//this is where it fails. delegate is nil
delegate!.expandCollapse!()
}
}
在UIView中,委托总是为零。我错过了什么?
答案 0 :(得分:0)
我对ARC的理解并不完全有信心,但我认为问题在于你的代表是一个弱的参考,并且在它设置之后没有任何关于代表的参考,所以它'解除分配。
替换它,我相信它会起作用:
var delegate:MyViewDelegate?
答案 1 :(得分:0)
尝试将代表分配给“myview”,然后再将其添加到“theview”
答案 2 :(得分:0)
使用委托就是不合适的。你正在与UIKit的设计模式作斗争。
整个情况非常简单。
你有你的ViewController。 然后你就拥有了完全独立的自定义视图。
基本上,您希望以某种方式从按钮路由TouchUpInside事件以获取viewController。
如果您的自定义视图包含按钮,则默认情况下此按钮的辅助功能级别为internal
。查看代码,我假设您在“接口”构建器中创建了该按钮。从自定义视图类到按钮创建一个插座,以便以编程方式访问它。
您的视图控制器声明此自定义视图的实例。然后,在viewDidLoad
中,您必须使用目标操作模式。
self.customView.button.addTarget(target: self, action: "expandCollapse", forControlEvents: .TouchUpInside)
这基本上就是它的所有内容。
答案 3 :(得分:0)
问题出在loadNib()成员函数中。 您正在创建两个" MyView"的实例。第二个实例被添加为子视图。
您在一个实例中设置委托并在另一个实例中引用nil委托。
尝试使用如下所示的静态类方法创建一个" MyView"
的实例class func loadFromNib() -> MyView? {
guard let myView = Bundle.main.loadNibNamed("MyView", owner: nil, options: nil)?.first as? MyView else {
assertionFailure("Failed to load nib for 'MyView'!")
return nil
}
return myView
}
这样做,你也不需要自定义init()。
希望有所帮助!