协议委托始终为零

问题描述 投票:0回答:1

我对使用xib文件不熟悉。所以我不清楚他们如何与父母互动。

我有一个自定义视图(LoginView),它是从xib文件创建的。该视图还定义了协议(LoginDelegate)。委托的唯一目的是将用户名和密码传递回呼叫者。

我也有一个实现此协议的ViewController(LoginVC)。我正在将LoginView添加到此VC。

我已验证我已在VC.viewDidLoad()中正确设置了委托。问题是当我尝试使用委托来调用协议方法时:委托始终为nil。不知何故它被清除了。这是UIView:

// MARK:- Login Delegate method
// provide a means to pass the user credentials back to the parent
protocol LoginDelegate: AnyObject {
    func getUsernameAndPassword(user: String, pwd: String)
}

class LoginView: UIView, UITextViewDelegate {

    @IBOutlet weak var userName: UITextView!
    @IBOutlet weak var password: UITextView!
    @IBOutlet weak var btnLogin: UIButton!
    var userPlaceholderLabel : UILabel!
    var pwdPlaceholderLabel : UILabel!
    var view: UIView!

    weak var loginDelegate: LoginDelegate?


    // MARK:- internal use only
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        loadViewFromNib()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        loadViewFromNib()
    }

    private func loadViewFromNib() {
        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
        let view = nib.instantiate(withOwner: self, options: nil).first as! UIView


        // handle placeholder text
//        userName.delegate = self      // set in Interface Builder
        userPlaceholderLabel = UILabel()
        userPlaceholderLabel.text = "Username"
        userName.addSubview(userPlaceholderLabel)

//        password.delegate = self.    // set in Interface Builder
        pwdPlaceholderLabel = UILabel()
        pwdPlaceholderLabel.text = "Password"
        password.addSubview(pwdPlaceholderLabel)

        view.frame = bounds
        view.autoresizingMask = [ UIView.AutoresizingMask.flexibleWidth, UIView.AutoresizingMask.flexibleHeight ]
        self.addSubview(view)
//        self.view = view
    }

    @IBAction func onLoginButtonPress(_ sender: Any) {
        print ("\(#function): Username: \(userName.text ?? ""), Password: \(password.text ?? "")")
        }
// THE DELEGATE IS ALWAYS NIL AT THIS POINT!
        self.loginDelegate?.getUsernameAndPassword(user: userName.text, pwd: password.text )
    }

    // MARK:- TextView Delegate methods
    func textViewDidChange(_ textView: UITextView) {...}  
    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {...}
}

和视图控制器:

class LoginVC: UIViewController, LoginDelegate {

    var isBleScan = true
    @IBOutlet weak var btnToggleBleScan: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
// I tried building the child view by creating it from a xib and by instantiating the class 
//    directly. While both approaches behave differently, neither works.
//        let vc = UINib(nibName: "LoginView", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! LoginView

        let loginSubview = LoginView()
        loginSubview.loginDelegate = self   // I verified this sets the delegate to an instance of LoginVC
        view.addSubview(loginSubview)
    }

    @IBAction func onToggleScanPressed(_ sender: Any) {
        isBleScan = !isBleScan
        if (isBleScan) {
            btnToggleBleScan.setTitle("Stop Scan", for: UIControl.State.normal)
        } else {
            btnToggleBleScan.setTitle("Start Scan", for: UIControl.State.normal)
        }
    }

    // MARK:- LoginDelegate methods
// METHOD IS NEVER CALLED - DELEGATE IS nil IN THE CALLER
    func getUsernameAndPassword(user: String, pwd: String) {
        let _user = user
        let _pwd = pwd
        print ("\(#function):Username: \(_user), Password: \(_pwd)")        
    }
}

我怀疑我在IB中接线不正确,但不确定。我找到了有关此问题的许多答案。我尝试了许多建议的解决方案,但没有任何效果。感谢您的投入!

ios swift uiview delegates xib
1个回答
0
投票

创建

  class func getInstance() -> LoginView { 
    let nib = UINib(nibName:"LoginView", bundle:nil)
    let view = nib.instantiate(withOwner: self, options: nil).first as! LoginView
    return view
  }

然后

    let loginSubview = LoginView.getInstance()
    loginSubview.frame = self.view.bounds
    loginSubview.loginDelegate = self   // I verified this sets the delegate to an instance of LoginVC
    view.addSubview(loginSubview)

然后删除此功能loadViewFromNib

© www.soinside.com 2019 - 2024. All rights reserved.