You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift4下适配键盘移动视图后发送消息屏幕变黑问题求解

解决Swift4通用消息VC发送消息后屏幕黑屏的问题

嘿,我来帮你搞定这个发送消息后屏幕变黑的麻烦!结合你提到的添加键盘适配代码后出现的问题,大概率是键盘通知处理或者视图布局逻辑出了问题,下面给你几个常见的排查和解决方向:

1. 检查键盘通知是否正确移除

很多人只记得在viewDidLoad里添加键盘观察者,却忘了在控制器销毁时移除,这会导致重复触发通知、内存泄漏,甚至引发界面布局异常。

解决办法:在控制器的deinit方法里移除观察者:

deinit {
    NotificationCenter.default.removeObserver(self)
}

2. 修正键盘收起时的视图复位逻辑

发送消息后通常会收起键盘,如果你的keyboardWillHide方法里视图复位的逻辑错误(比如偏移量计算不对、动画未正确执行),会导致视图被移到屏幕外,露出window的黑色背景,也就是你看到的黑屏。

举个正确的复位示例(假设你用ScrollView承载消息列表):

@objc func keyboardWillHide(_ notification: Notification) {
    guard let keyboardFrame = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? CGRect else { return }
    let animationDuration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? Double ?? 0.25
    
    UIView.animate(withDuration: animationDuration) {
        // 将scrollView的偏移量还原到键盘弹出前的状态
        self.messagesScrollView.contentOffset.y -= keyboardFrame.height
    }
}

如果是直接移动整个控制器的view,要确保复位到初始位置:

UIView.animate(withDuration: animationDuration) {
    self.view.frame.origin.y = 0
}

3. 改用Auto Layout约束适配键盘(更可靠)

手动修改view的frame很容易和Auto Layout约束冲突,导致布局错乱引发黑屏。推荐给输入框的底部约束创建一个IBOutlet,通过修改约束值来适配键盘:

步骤:

  • 给输入框的底部约束添加IBOutlet:
    @IBOutlet weak var inputBottomConstraint: NSLayoutConstraint!
    
  • 调整键盘通知的处理逻辑:
    @objc func keyboardWillShow(_ notification: Notification) {
        guard let keyboardFrame = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? CGRect else { return }
        let animationDuration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? Double ?? 0.25
        
        inputBottomConstraint.constant = keyboardFrame.height
        UIView.animate(withDuration: animationDuration) {
            self.view.layoutIfNeeded()
        }
    }
    
    @objc func keyboardWillHide(_ notification: Notification) {
        let animationDuration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? Double ?? 0.25
        
        inputBottomConstraint.constant = 0 // 还原到初始底部间距
        UIView.animate(withDuration: animationDuration) {
            self.view.layoutIfNeeded()
        }
    }
    

4. 避免发送消息逻辑与键盘动画冲突

发送消息后你可能会刷新消息列表,如果这个操作和键盘收起动画同时执行,可能导致ScrollView的contentOffset计算错误,引发界面偏移。

解决办法:等键盘完全收起后再刷新列表:

func sendButtonTapped() {
    // 1. 收起键盘
    messageTextField.resignFirstResponder()
    
    // 2. 执行发送消息的逻辑
    if let messageText = messageTextField.text, !messageText.isEmpty {
        // 发送消息代码...
        messageTextField.text = ""
    }
    
    // 3. 等键盘动画完成后再刷新列表并滚动到最新消息
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
        self.messagesTableView.reloadData()
        if self.messages.count > 0 {
            let lastIndexPath = IndexPath(row: self.messages.count - 1, section: 0)
            self.messagesTableView.scrollToRow(at: lastIndexPath, at: .bottom, animated: true)
        }
    }
}

你可以先从检查通知移除和键盘收起的复位逻辑开始排查,这两个是最常见的原因。如果还是有问题,建议改用Auto Layout的方式适配键盘,会减少很多布局冲突的问题。

内容的提问来源于stack exchange,提问作者naga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:11:29