2016-03-30 14 views
0

私はMyViewとView ControllerというカスタムUIViewクラスを持っています。代理人は常にゼロです

ユーザーがUIViewのボタンをタップすると、View Controllerで関数を呼び出す必要があります。私は

カスタムUIClass

@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のマイビューコントローラ

class ViewController2: UIViewController, MyViewDelegate { 

@IBOutlet weak var theview: UIView! 
var myview : MyView? 


override func viewDidAppear(animated: Bool) { 
    super.viewWillAppear(animated) 
    myview = MyView(frame: CGRectMake(0,0,theview.frame.size.width,theview.frame.size.height)) 
    self.theview.addSubview(myview!) 


     myview!.delegate = self 
    } 

func expandCollapse() { 
    viewheight.constant = 172 
    UIView.animateWithDuration(0.5) { 
     self.view.layoutIfNeeded() 

    } 
} 

代表団を介してこれを実現しようとしている、デリゲートは常にnilです。私は何が欠けていますか?

+0

あなたはレスポンダーチェーンを知っていますか? –

答えて

0

を追加する前に、「MYVIEW」にデリゲートを割り当ててみは単純には不向きです。あなたはUIKitデザインパターンと戦っています。

全体の状況は非常に簡単です。

ViewControllerがあります。 それから完全に独立したカスタムビューがあります。

本質的に、どういうわけかは、TouchUpInsideイベントをボタンからルーティングしてviewControllerに到達させたいと考えています。

カスタム表示にボタンが含まれている場合、このボタンのアクセシビリティレベルはデフォルトでinternalになります。コードを見ると、Interface Builderのボタンを作成したと仮定します。カスタムビュークラスからボタンへのコンセントを作成し、プログラムでアクセス可能な参照ができるようにします。

ビューコントローラは、このカスタムビューのインスタンスを宣言します。次に、viewDidLoadにはターゲットアクションパターンを使用する必要があります。

self.customView.button.addTarget(target: self, action: "expandCollapse", forControlEvents: .TouchUpInside) 

これは基本的にすべてです。

0

私はARCの理解を完全には信じていませんが、あなたの代理人は弱い参照であり、設定後に代理人への参照を保持するものがないので、割り当てが解除されます。

はこれでそれを交換し、私はそれが動作すると信じて:

のvarデリゲート:MyViewDelegate?

+0

申し訳ありませんが、まだ同じ問題が発生しています – prawn

0

このために委任を使用する「theview」に

+0

私はそのことを期待していました...しかし、 – prawn

0

問題は、loadNib()メンバー関数にあります。 "MyView"という2つのインスタンスを作成しています。 2番目のインスタンスはサブビューとして追加されます。

デリゲートを1つのインスタンスに設定し、他のインスタンスの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 
} 

の1つのインスタンスを作成するには、以下のようなクラスの静的メソッドを使用してみてください、あなたは(が)のいずれか■カスタムの初期化を必要としません。

希望に役立ちます!