从子视图访问属性到ViewController Swift

时间:2016-12-11 16:35:12

标签: swift uiview uiviewcontroller xib

我如何访问我的子视图的属性到viewcontroller。

示例:如果我有一个@IBOutlet弱变量loginBtn:UIButton!如何访问我的视图控制器?我做了很多事情和教程如何做到这一点,但我仍然没有设法让它工作。

而且我也很困惑加载xib的最佳方法是什么?我在教程中看到了很多方法,但我也想知道他们是如何在生产应用程序中完成的。

protocol UserLoginDelegate {
   func userDidLogin(status: Bool, message: String)
}

@IBDesignable class LoginWidget: UIView {

   var loginDelegate: UserLoginDelegate?
   var loginView: UIView!
   var nibName: String = "LoginWidget"

   let defaults = NSUserDefaults.standardUserDefaults()

   @IBOutlet weak var loginButton: UIButton!
   @IBOutlet weak var email: UITextField!
   @IBOutlet weak var password: UITextField!
   @IBOutlet weak var name: UITextField!
   @IBAction func loginBtn(sender: AnyObject) {

   // init
   override init(frame: CGRect) {
      super.init(frame: frame)

      // set anything that uses the view or visible bounds
      setup()
   }

   required init?(coder aDecoder: NSCoder) {
      super.init(coder: aDecoder)

      // setup
      setup()
   }

   func setup() {
      loginView = loadViewFromNib()
      loginView.frame = bounds
      loginView.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight]

      addSubview(loginView)

   }

   func loadViewFromNib() -> UIView {
      let bundle = NSBundle(forClass: self.dynamicType)
      let nib = UINib(nibName: nibName, bundle: bundle)
      let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView

      return view
   }

}

控制器

class AuthenticationViewController: UIViewController, UserLoginDelegate {
      override func viewDidLoad() {
        super.viewDidLoad()

         loginWidget = LoginWidget(frame: CGRect(x: 0, y: 171, width: 375, height: 247))
         authenticationSegment.setEnabled(true, forSegmentAtIndex: 0)
         loginWidget.loginDelegate = self
         self.view.addSubview(loginWidget)

        // Do any additional setup after loading the view.
    }
}

1 个答案:

答案 0 :(得分:0)

首先,关于SO:这里的目标是拥有一个遵循模式的众包源知识库(一个本体!)。普通用户喜欢以下形式提出的问题:

我对此感到困惑。我想完成这个非常具体的事情。这是我尝试过的代码。我认为这是问题所在。你能告诉我如何正确地做到这一点或让它运作吗?

因此,最终我们得到了一长串直接解决方案的索引可搜索问题列表。这些愚蠢的,非特定的,多问题,令人困惑的帖子倾向于被低估,被忽视,被告知改写等等。

我会解答你的问题:

  

如果我有一个@IBOutlet弱var loginBtn:UIButton!我怎么才能访问   那对我的视图控制器?我做了很多事情和教程如何   要做到这一点,但我仍然没有设法让它发挥作用。

使用UIButton或任何UIControl子类,您可以将@IBAction拖动到视图控制器中。通过从有问题的故事板按钮拖动到您的代码(与制作插座的方式相同),然后从下拉菜单中选择操作来完成此操作。然后你可以选择改变发送这个动作的对象的类型(它是一个UIButton,还是任何人都可以调用这个方法,它恰好被链接到按钮),或者你可以改变它被调用的控件事件(也就是说,当他们触摸按钮上的DOWN或者手指仍然触摸按钮时触摸,这是默认值。)

更一般地说,如果你有一个不是控件的复杂视图,你可以随时添加一个手势识别器(即UITapGestureRecognizer)并从中拖动一个IBAction,(将手势识别器拖到视图上,然后从在左侧窗格中,按住Ctrl键从手势录制到您的代码并再次选择操作。

最后,这比你当前需要的还要多,但是如果你有一个必须通知视图控制器的视图,或者告诉视图控制器(或任何对象)做类似的事情,请发送给我#34数据请",您可以使用委托模式。简单地说:您定义一个协议来列出协议所需的方法和变量。通过为每个方法提供一个实现,然后在视图中放置一个变量,使您的委托对象符合此协议

weak var delegate: MyProtocol?

委托模式在Swift中很重要,您应该阅读它。例如,如果您使用了表视图,则可能已经使用过它。

  

而且我也不知道加载xib的最佳方法是什么?那里有很多   我在教程中看到的方式,但我也想知道他们是如何做到的   生产应用程序。

以下是我如何启动xib文件所有者的每个视图。我相信这是正确的方法,如果这是错误的话,我会很感激。这是快速3,你应该在这一点上使用它......它好多了!

@IBOutlet var mainView: UIView!
// the above is the outlet from the xib's main view. which I always call main view

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

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    combinedInit()
}


func combinedInit(){

    Bundle.main.loadNibNamed("XibFileName", owner: self, options: nil)
    addSubview(mainView)
    mainView.frame = self.bounds
    // more initialization stuff
}