2017-07-31 78 views
1

我最近开始学习Swift。当我试图让我的第一个App我与UIBarButtonItem混淆。如果我在viewDidLoad()函数之外放置UIBarButtonItem初始值,当按下一个按钮时不会发生任何反应。Swift,与UIBarButtonItem混淆

class ViewController: UIViewController, UITextFieldDelegate { 
    let rightBarButton: UIBarButtonItem = UIBarButtonItem(title: "Next", style: .plain, target: self, action: #selector(onClickNext(button:))) 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     self.view.backgroundColor = .white 

     self.navigationItem.rightBarButtonItem = rightBarButton 
    } 

    func onClickNext(button: UIBarButtonItem) { 
     print("should push view controller") 
    } 
} 

然而,当我把initializationviewDidLoad()功能,输出方面的确输出,我在onClickNext(button:)功能设置的sentense。

class ViewController: UIViewController, UITextFieldDelegate { 
    var rightBarButton: UIBarButtonItem? 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     self.view.backgroundColor = .white 

     self.rightBarButton = UIBarButtonItem(title: "Next", style: .plain, target: self, action: #selector(onClickNext(button:))) 
     self.navigationItem.rightBarButtonItem = rightBarButton 
    } 

    func onClickNext(button: UIBarButtonItem) { 
     print("should push view controller") 
    } 
} 

而且,我我发现,当我把initializationviewDidLoad()功能外,还加了一个UITextFieldviewControllerrightBarButton作品,如果我碰textfield之前,我按下按钮。

这让我感到困惑。什么是机制?

+0

非常好的问题 –

+0

这应该是一个错误,你可以参考一下这个问题:https://stackoverflow.com/questions/43842928/ios-lazy-var-uibarbuttonitem-target-issue – user5685969

回答

0

好吧,也许你缺少一个视图控制器的工作机制。

首先,viewDidLoad是您通常在区域设置或初始化视图的任何视图或属性。在视图控制器对象的生命周期中,该方法也仅被调用一次。这意味着self已经存在。

知道了这一点,重要的是要了解let属性确实,(苹果)

恒定声明定义的不可改变常量名和初始化表达式的值之间的结合什么;在设定常数值后,不能更改。也就是说,如果一个常量是用一个类对象初始化的,那么该对象本身可以改变,但是常量名和它引用的对象之间的绑定不能。

即使上部区域是你声明的变量和常量,通常意味着简单的初始化,这是一个面积只是告诉VC的存在,你要使用的对象,将有一类全局范围,但是当视图层次结构被加载时(意味着对象不依赖于自己,例如,将目标添加到按钮时,指的是自己内部的方法),将添加其余的功能。 ..这个变量或常量被称为Stored Properties

以最简单的形式,存储的属性是一个常量或变量,存储为一个实例的一部分特定类别或结构。存储属性可以是变量存储属性(由var关键字引入)或常量存储属性(由let关键字引入)。

最后,你有懒存储的属性,也许可以应用于你想要的东西:

懒惰的存储属性是一个属性,它的初始值不计算直到第一次它被使用。通过在声明之前编写lazy修饰符来指示惰性存储属性。

解决方案:创建一个懒惰的VAR存储的属性或添加自己的属性里面viewDidLoad中(自检时已经存在)

lazy private var doneButtonItem : UIBarButtonItem = { 
    [unowned self] in 
    return UIBarButtonItem(title: "Next", style:UIBarButtonItemStyle.Plain, target: self, action: #selector(onClickNext(button:))) 
    }() 

OR

let rightBarButton: UIBarButtonItem? 

override func viewDidLoad() { 
     super.viewDidLoad() 
     rightBarButton = UIBarButtonItem(title: "Next", style: .plain, target: self, action: #selector(onClickNext(button:))) 
} 
+1

谢谢!这解决了我的第一个问题。现在我对第二个问题感到好奇:如果在按下按钮之前触摸文本字段,为什么它会起作用? – Leadrains

+0

@ user5685969说它可能是一个错误引用的问题:https://stackoverflow.com/questions/43842928/ios-lazy-var-uibarbuttonitem-target-issue – Leadrains

+0

你是否添加UITtexField而不设置它的委托?你如何通过代码或xib添加这个控件?这可能是一个错误,但我需要更多信息 –

0
import UIKit 


    class ViewController: UIViewController { 

     var btnName = UIButton() 



     override func viewDidLoad() { 
      super.viewDidLoad() 
      btnName.setImage(UIImage(named: "imagename"), for: .normal) 
      btnName.frame = CGRect(x:0,y: 0,width: 30,height: 30) 
      btnName.addTarget(self, action: #selector(addTargetActionForButton(:_)), for: .touchUpInside) 

      let rightBarButton = UIBarButtonItem(customView: btnName) 
      self.navigationItem.rightBarButtonItem = rightBarButton 

     } 

     func addTargetActionForButton(_ sender : UIButton){ 


     } 
    } 
+0

感谢。但我知道如何使它工作,我只是混淆了为什么当我将初始化放在viewDidLoad()函数之外时它不起作用。 – Leadrains

0

你正在采取让变量出侧viewDidLoad你不能让让全局变量。如果你想让你比你需要在viewDidLoad中声明。富勒更多信息,让和VAR检查此链接What is the difference between `let` and `var` in swift?

override func viewDidLoad() { 

    let rightBarButton: UIBarButtonItem = UIBarButtonItem(title: "Next", style: .plain, target: self, action: #selector(onClickNext(button:))) 

    super.viewDidLoad() 
    self.view.backgroundColor = .white 

    self.navigationItem.rightBarButtonItem = rightBarButton 


} 
+0

我使它变量变量,仍然把viewDidLoad()函数以外的初始化,但它仍然无法工作.. – Leadrains

+0

但我检查了让和var它工作正常我的结局 –

+0

没有问题是,如果点击textfield按钮完美工作,否则不是 –

0

UIBatButtonItem可能包含的UIButton

enter image description here 上面的例子中的图像具有UINavigationItem含有LeftBarButtonItems([UIBarButton]),和RightBarButtonItems([的UIBarButtonItem]),每个的UIBarButtonItem包含的UIButton

我们可以自定义的UIButton指定如何在查看 显示和我们可以连接按钮操作直接到UIButton的