【问题标题】:Input accessory view from one view controller incorrectly appears in another view controller来自一个视图控制器的输入附件视图错误地出现在另一个视图控制器中
【发布时间】:2018-06-01 19:34:11
【问题描述】:

我在我的应用程序中遇到了一个错误,尽管我覆盖了输入附件视图,但第一个视图控制器中的 UIToolbar 出现在第三个视图控制器中。

第一个视图控制器:

class FirstViewController: BaseViewController {

    @IBOutlet weak var toolbar: UIToolbar!

    override var inputAccessoryView: UIView? {
        return toolbar
    }

    ...

第二个视图控制器:

class SecondViewController: BaseViewController {

    override var inputAccessoryView: UIView? {
        return nil
    }

    ...

第三视图控制器:

class ThirdViewController: BaseViewController {

    override var inputAccessoryView: UIView? {
        return nil
    }

    ...

我不确定是什么导致工具栏出现在第二个视图控制器中。这些视图控制器没有嵌入在 UINavigationController 中,所以我不明白它是如何转移到另一个屏幕上的。

【问题讨论】:

  • 似乎有点奇怪 - 听起来像 FirstViewController 永远不会辞去响应者的职务,因此输入附件视图“继续存在”。也许将resignFirstResponder() 放入viewWillDisappear() 放入FirstViewController
  • @DonMag 这确实有效,但我发现了另一种无效的情况。当我在 UINavigationController 中显示另一个视图控制器时,会出现之前两个屏幕的输入附件视图。这是一个非常奇怪的情况。

标签: ios swift


【解决方案1】:

所以这是一个很难解决的问题,但我最终找到了问题。

所以问题在于方法canBecomeFirstResponder。如果我们按如下方式设计故事板:

FirstViewController -(show)-> SecondViewController -(show )-> ThirdViewController

当我们转到ThirdViewController 时,iOS 会询问FirstViewController 是否可以成为第一响应者。如果canBecomeFirstResponder返回true,那么FirstViewController的输入附件视图会出现在ThirdViewController中。

不幸的是,这个解决方案有点老套,但这是我目前能想到的唯一解决方案。

基础视图控制器:

class BaseViewController: UIViewController {

    var shouldBecomeFirstResponder: Bool = false

    override var canBecomeFirstResponder: Bool {
        return shouldBecomeFirstResponder
    }

    ...
}

第一个视图控制器:

class FirstViewController: BaseViewController {

    @IBOutlet weak var toolbar: UIToolbar!

    override func viewDidLoad() {
        super.viewDidLoad()
        shouldBecomeFirstResponder = true
    }

    override var inputAccessoryView: UIView? {
        return toolbar
    }

    @IBAction didTap() {
        shouldBecomeFirstResponder = false
        performSegue(withIdentifier: "showSecond", sender: self)
    }
    ...
}

第二个视图控制器:

class SecondViewController: BaseViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        shouldBecomeFirstResponder = false
    }
    ...

    @IBAction didTap() {
        performSegue(withIdentifier: "showThird", sender: self)
    }

    ...
}

第三视图控制器:

class ThirdViewController: BaseViewController {

    ...
}

【讨论】:

    【解决方案2】:

    如果 @entelect-ca 假设是正确的 - 如果控制器可见,我宁愿签入 FirstViewController

    此外,没有现成的方法来检查控制器是否可见(尤其是在处理选项卡时)。所以你可以将visible 属性添加到你的视图控制器中:

    @property BOOL visible;
    
    - (void)viewDidAppear:(BOOL)animated {
        [super viewDidAppear:animated];
        self.visible = true;
    }
    
    - (void)viewDidDisappear:(BOOL)animated {
        [super viewDidDisappear:animated];
        self.visible = false;
    }
    
    - (BOOL)canBecomeFirstResponder {
        return self.visible;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多