【问题标题】:Swift, confusion with UIBarButtonItemSwift,与 UIBarButtonItem 混淆
【发布时间】:2017-07-31 06:05:36
【问题描述】:

我最近开始学习 Swift。当我尝试制作我的第一个 App 时,我对 UIBarButtonItem 感到困惑。如果我把 let UIBarButtonItem 初始化放在 viewDidLoad() 函数之外,当我按下 Next 按钮时什么也不会发生。

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")
    }
}

但是,当我将initialization 放入viewDidLoad() 函数时,输出区域确实输出了我在onClickNext(button:) 函数中设置的句子。

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")
    }
}

另外,我发现当我将initialization 放在viewDidLoad() 函数之外,并在viewController 中添加UITextField 时,如果我在按下之前触摸textfieldrightBarButton 就会起作用按钮。

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

【问题讨论】:

标签: ios swift uibarbuttonitem


【解决方案1】:

好吧,也许您错过了 ViewController 内部的工作方式。

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

了解这一点对于了解 let 属性的作用非常重要,(来自 Apple)

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

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

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

最后,你有一个惰性存储属性,也许可以应用到你想要的东西:

惰性存储属性是在第一次使用之前不计算初始值的属性。您可以通过在声明之前编写惰性修饰符来指示惰性存储属性。

解决方案:创建一个惰性 var 存储属性或在 ViewDidLoad 中添加他的属性(当 self 已经存在时)

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

let rightBarButton: UIBarButtonItem?

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

【讨论】:

  • 谢谢!这解决了我的第一个问题。现在我对第二个问题很好奇:为什么我在按下按钮之前触摸文本字段会起作用?
  • @user5685969 说这可能是一个错误,请参阅问题:stackoverflow.com/questions/43842928/…
  • 您是否在不设置委托的情况下添加了 UITtexField?您如何通过代码或 xib 添加此控件?这可能是一个错误,但我需要更多信息
  • 我只是添加了 UITextField 而没有通过代码设置它的委托。然后我发现:如果我将 UIBarButtonItem 初始化放在 viewDidLoad() 函数之外,目标操作永远不会起作用,但是在我触摸文本字段后,它会意外地起作用。
  • 我认为这与文本字段的代表无关。我可以通过按下文本字段来解释 iOS 如何运行以使目标操作再次起作用。
【解决方案2】:
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){


        }
    }

【讨论】:

  • 谢谢。但是我知道如何使它工作,我只是混淆了为什么当我将初始化放在 viewDidLoad() 函数之外时它不起作用。
【解决方案3】:

您正在将 let 变量从 viewDidLoad 中取出 您不能将 let 全局变量取出。如果你想要让而不是你需要在 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


}

【讨论】:

  • 我将它设为 var 变量,仍然将初始化放在 viewDidLoad() 函数之外,但它仍然不起作用..
  • 但是我检查了 let 和 var 对我来说效果很好
  • 不,问题是如果单击文本字段按钮可以正常工作,否则不会
【解决方案4】:

UIBatButtonItem 可能包含 UIButton

上面的示例图像有 UINavigationItem,其中包含 LeftBarButtonItems ([UIBarButton]) 和 RightBarButtonItems([UIBarButtonItem]),每个 UIBarButtonItem 都包含 UIButton

我们可以自定义UIButton来指定如何在View中显示 我们可以将按钮操作直接连接到 UIButton

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-23
    • 1970-01-01
    • 1970-01-01
    • 2014-07-09
    • 1970-01-01
    • 2016-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多