【问题标题】:iMessage extension crashes while trying to access UITextView in compact modeiMessage 扩展程序在尝试以紧凑模式访问 UITextView 时崩溃
【发布时间】:2017-11-15 00:36:22
【问题描述】:

以下是我在 iMessage 应用程序中的全部代码。

class MessagesViewController: MSMessagesAppViewController {

@IBOutlet weak var messageView: UITextView!

fileprivate func setupMessageView() {
    messageView.delegate = self

    messageView.layer.cornerRadius = 10
    messageView.layer.borderColor = UIColor.black.cgColor
    messageView.layer.borderWidth = 5

    messageView.text = "Tap to enter a message"
    messageView.textColor = UIColor(red:0.80, green:0.81, blue:0.82, alpha:1.0)
    messageView.textAlignment = .center

    messageView.font = UIFont.systemFont(ofSize: 20)

    messageView.textContainerInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
}

func initialize() {
    setupMessageView()
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    self.view.endEditing(true)
}

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(self.initialize), userInfo: nil, repeats: false)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// MARK: - Conversation Handling

override func willBecomeActive(with conversation: MSConversation) {
    // Called when the extension is about to move from the inactive to active state.
    // This will happen when the extension is about to present UI.

    // Use this method to configure the extension and restore previously stored state.
}

override func didResignActive(with conversation: MSConversation) {
    // Called when the extension is about to move from the active to inactive state.
    // This will happen when the user dissmises the extension, changes to a different
    // conversation or quits Messages.

    // Use this method to release shared resources, save user data, invalidate timers,
    // and store enough state information to restore your extension to its current state
    // in case it is terminated later.
}

override func didReceive(_ message: MSMessage, conversation: MSConversation) {
    // Called when a message arrives that was generated by another instance of this
    // extension on a remote device.

    // Use this method to trigger UI updates in response to the message.
}

override func didStartSending(_ message: MSMessage, conversation: MSConversation) {
    // Called when the user taps the send button.
}

override func didCancelSending(_ message: MSMessage, conversation: MSConversation) {
    // Called when the user deletes the message without sending it.

    // Use this to clean up state related to the deleted message.
}

override func willTransition(to presentationStyle: MSMessagesAppPresentationStyle) {
    // Called before the extension transitions to a new presentation style.

    // Use this method to prepare for the change in presentation style.
}

override func didTransition(to presentationStyle: MSMessagesAppPresentationStyle) {
    // Called after the extension transitions to a new presentation style.

    // Use this method to finalize any behaviors associated with the change in presentation style.
}

}

extension MessagesViewController: UITextViewDelegate {
func textViewDidBeginEditing(_ textView: UITextView) {
    if textView == messageView {
        requestPresentationStyle(.expanded)
        if textView.textColor == UIColor(red:0.80, green:0.81, blue:0.82, alpha:1.0) {
            textView.text = nil
            textView.textAlignment = .left
            textView.textColor = UIColor.black
            textView.font = UIFont.systemFont(ofSize: 20)
        }
    }
}

func textViewDidEndEditing(_ textView: UITextView) {
    if textView == messageView {
        if textView.text.isEmpty {
            textView.text = "Tap to enter a message"
            textView.textAlignment = .center
            textView.textColor = UIColor(red:0.80, green:0.81, blue:0.82, alpha:1.0)
            textView.font = UIFont.systemFont(ofSize: 20)
        }
    }
}
}

它有一个UITextView,我尝试输入数据。我在执行此操作时遇到了一个奇怪的问题。

在初始加载时,如果我点击UITextView,则会调用扩展模式,但键盘不会向上滑动。它需要再次点击键盘才能向上滑动。

在日志中,我发现textViewDidBeginEditingtextViewDidEndEditing 方法在第一次点击时被连续调用。不确定,为什么会这样!?

无论如何,让我更感兴趣的是现在发生的事情。我可以手动将模式更改为紧凑,然后返回扩展。如果在扩展模式下,一旦我点击,键盘就会向上滑动。但是,如果我在紧凑模式下点击,应用就会崩溃!!

而且这种情况一直都在发生。在模拟器和真实设备上。我不知道如何解释这种行为。

无论我将模式从紧凑更改为扩展再返回多少次,我都可以在扩展模式下输入文本。但是,在第一次点击之后,它就再也不会发生了,而在紧凑模式下。

有人有这个问题吗?或者你能复制这个吗?这是 Apple 的错误吗?

【问题讨论】:

  • 这听起来类似于我在调用becomeFirstResponder 时遇到的问题,方法与调用requestPresentationStyle 的方法相同。混合这些是自找麻烦。如果您确保在转换完成之前文本字段不会成为第一响应者,这可能会有所帮助。
  • @TomHarrington,好的。所以,我没有明确使用becomeFirstResponder。或者,你的意思是在textViewDidBeginEditing 中使用requestPresentationStyle 是一样的吗?那么,我们如何识别UITextView被窃听了呢?
  • @TomHarrington,或者如何确保UITextView 在转换完成之前不会成为第一响应者。顺便说一句,didTransition(to presentationStyle: ) 不起作用。 ¯_(ツ)_/¯
  • 在我的例子中,我们只是没有显示文本视图。在紧凑模式下,有一个按钮,文本视图在展开模式下可见。您也可以通过在紧凑模式下禁用编辑但添加轻击手势识别器来做到这一点,以便轻击文本字段启动更改,但在更改完成之前它不会成为第一响应者。
  • @TomHarrington,你。是。简单地。惊人的。期间。

标签: ios swift swift3 uitextview imessage-extension


【解决方案1】:

如果您需要在用户点击文本字段后更改演示样式,您可以添加延迟以确保不会与过渡发生冲突。

最初阻止键盘显示可能会更好(您可能需要在 VC 中设置一个 bool 标志以在您的 textview 委托中关闭以启用此功能),调用

  func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
    if  !shouldShowKeyBoard {
        self.requestPresentationStyle(.expanded)
        return false
    }
    return true

然后在 MSMessagesAppViewController 委托中启用键盘成为第一响应者 `

 override func didTransition(to presentationStyle: MSMessagesAppPresentationStyle) {
    if presentationStyle == .expanded {
       shouldShowKeyBoard = true
       textView.becomeFirstResponder()
    }
}

`

希望对你有所帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-14
    • 2023-03-06
    • 1970-01-01
    相关资源
    最近更新 更多