【问题标题】:Attempt to present which is already presenting尝试呈现已经呈现的内容
【发布时间】:2017-02-17 22:40:33
【问题描述】:

我要做的就是在我长时间触摸时在当前上下文中调用新控制器(UILongPressGestureRecognizer)。 代码如下:

class ViewController: UIViewController {

@IBOutlet weak var button: UIButton!{
    didSet{
        button.addGestureRecognizer(UILongPressGestureRecognizer(target: self,
                                                                 action: #selector(settingTheButton(_:))))
    }
}

func settingTheButton(_ recognizer: UILongPressGestureRecognizer){
    print("touchTheColorButton was called") // here the method invokes twice
    if let button = recognizer.view as? UIButton{
        performSegue(withIdentifier: "setTheButtonColor", sender: button)
    }
}

override func viewDidLoad() {
    super.viewDidLoad()
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?){
    if segue.identifier == "setTheButtonColor", let vc = segue.destination as? SettingsForButtonVC, let senderButton = sender as? UIButton {
        vc.button = senderButton
    }
}
}

我不明白。为什么方法 settingTheButton 被调用了两次?它不会干扰或损害程序,但它确实让我感到不安。

控制台: touchTheColorButton 被调用 touchTheColorButton 被调用 2017-02-18 01:28:12.499552 测试[1042:223223] 警告:尝试展示已经展示的对象

【问题讨论】:

  • 将 segue 的发件人更改为自己,并删除您的 prepareForSegue 方法的按钮。

标签: ios iphone swift uikit


【解决方案1】:

你的问题是你没有听到手势的状态。

改为:

func settingTheButton(_ recognizer: UILongPressGestureRecognizer){
    guard recognizer.state == .ended else { return }

    print("touchTheColorButton was called") // here the method invokes twice
    if let button = recognizer.view as? UIButton{
        performSegue(withIdentifier: "setTheButtonColor", sender: button)
    }
}

我没有正确测试。在否决之前让我知道它是否不起作用。

【讨论】:

    【解决方案2】:

    扩展@Marco Santarossa 给出的解决方案(无法评论)。这将正常工作:

    func settingTheButton(_ recognizer: UILongPressGestureRecognizer){
    
        // Get the button just as you have done
        if let button = recognizer.view as? UIButton{
    
            // Take only the `.ended` event, discarding any other ones
            if recognizer.state == .ended {
                performSegue(withIdentifier: "setTheButtonColor", sender: button)
            }
        }
    }
    

    您的代码的问题是每次在UILongPressGestureRecognizer 中触发事件时都会调用一次settingTheButton(_ recognizer:),而不仅仅是在释放您可能期望的行为的按钮时。这两个事件是.began(一旦按下被识别为长按)和.ended(释放长按后)。

    简单地忽略这两个将使您的代码只被调用一次,此外它在.ended 上更有意义,因为您可能希望在释放按钮后而不是在按下按钮期间出现新屏幕。

    注意:您知道,最好只允许.ended,因为除了我知道的这两个之外,至少还有一个其他常见事件可以触发。如果您使用的是强制触摸设备,.changed 将被调用多次,每次非常轻微的压力变化都会调用一次。

    【讨论】:

      猜你喜欢
      • 2017-05-24
      • 2015-04-21
      • 2016-10-20
      • 2021-11-05
      • 1970-01-01
      • 1970-01-01
      • 2017-01-07
      • 2014-10-02
      • 1970-01-01
      相关资源
      最近更新 更多