菜鸟教程小白 发表于 2022-12-11 18:24:10

ios - Swift,与 UIBarButtonItem 混淆


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

<pre><code>class ViewController: UIViewController, UITextFieldDelegate {
    let rightBarButton: UIBarButtonItem = UIBarButtonItem(title: &#34;Next&#34;, 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(&#34;should push view controller&#34;)
    }
}
</code></pre>

<p>但是,当我将<code>initialization</code>放入<code>viewDidLoad()</code>函数时,输出区确实输出了我在<code>onClickNext(button: )</code> 函数。 </p>

<pre><code>class ViewController: UIViewController, UITextFieldDelegate {
    var rightBarButton: UIBarButtonItem?

    override func viewDidLoad() {
      super.viewDidLoad()

      self.view.backgroundColor = .white

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

    func onClickNext(button: UIBarButtonItem) {
      print(&#34;should push view controller&#34;)
    }
}
</code></pre>

<p>另外,我发现当我将 <code>initialization</code> 放在 <code>viewDidLoad()</code> 函数之外时,我将 <code>UITextField</code> 添加到 <code> viewController</code>,如果我在按下按钮之前触摸 <code>textfield</code>,<code>rightBarButton</code> 就会起作用。 </p>

<p>这让我很困惑。机制是什么?</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>好吧,也许您错过了 ViewController 内部的工作方式。 </p>

<p>首先,<code>viewDidLoad</code> 是您通常<strong>设置或初始化任何 View 或 View 属性</strong>的区域。此方法在 ViewController 对象的生命周期内也只调用一次。这意味着 <code>self</code> 已经存在。</p>

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

<blockquote>
<p>A constant declaration defines an <strong>immutable</strong> binding between the constant name and the value of the initializer expression; after the value of a constant is set, it cannot be changed. That said, if a constant is initialized with a class object, the object itself can change, but the binding between the constant name and the object it refers to can’t.</p>
</blockquote>

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

<blockquote>
<p>In its simplest form, a stored property is a constant or variable that is stored as part of an instance of a particular class or structure. Stored properties can be either variable stored properties (introduced by the var keyword) or constant stored properties (introduced by the let keyword).</p>
</blockquote>

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

<blockquote>
<p>A lazy stored property is a property whose initial value is not calculated until the first time it is used. You indicate a lazy stored property by writing the lazy modifier before its declaration.</p>
</blockquote>

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

<pre><code>lazy private var doneButtonItem : UIBarButtonItem = {
    in
    return UIBarButtonItem(title: &#34;Next&#34;, style:UIBarButtonItemStyle.Plain, target: self, action: #selector(onClickNext(button:)))
    }()
</code></pre>

<p>或</p>

<pre><code>let rightBarButton: UIBarButtonItem?

override func viewDidLoad() {
      super.viewDidLoad()
      rightBarButton = UIBarButtonItem(title: &#34;Next&#34;, style: .plain, target: self, action: #selector(onClickNext(button:)))
}
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - Swift,与 UIBarButtonItem 混淆,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/45408498/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/45408498/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - Swift,与 UIBarButtonItem 混淆