代表总是零

时间:2016-03-30 23:22:34

标签: swift

我有一个名为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中,委托总是为零。我错过了什么?

4 个答案:

答案 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()。

希望有所帮助!