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

返回页面后UITextView无法滚动问题求助(附代码)

UITextView 返回后无法滚动的问题修复

问题现象

首次输入大量文本时,UITextView可正常滚动;跳转到第二个视图控制器后返回,UITextView失去滚动能力。移除placeholder label后问题消失,添加后复现。

问题原因

placeholderLabel被添加为UITextView的子视图,且设置了固定高度约束(60),同时开启translatesAutoresizingMaskIntoConstraints = false。返回页面重新填充文本时,该约束会强制限制UITextView的内容视图高度,导致滚动逻辑失效。

修复方案

  1. 移除placeholderLabel的固定高度约束,改用与UITextView字体行高匹配的动态约束,或直接不设置高度约束让label自适应内容;
  2. 确保placeholderLabel的隐藏状态与文本内容同步,避免干扰UITextView布局计算;
  3. 返回页面时手动触发UITextView布局更新,确保内容尺寸正确计算。

修改后的关键代码

1. 调整placeholderLabel约束(修改buildConstraints方法)

func buildConstraints() {
    // 其他控件约束保持不变
    nameLabel.translatesAutoresizingMaskIntoConstraints = false
    nameLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    nameLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20).isActive = true
    nameLabel.heightAnchor.constraint(equalToConstant: 60).isActive = true
    
    textView.translatesAutoresizingMaskIntoConstraints = false
    textView.topAnchor.constraint(equalTo: nameLabel.bottomAnchor, constant: 8).isActive = true
    textView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 8).isActive = true
    textView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -8).isActive = true
    textView.bottomAnchor.constraint(equalTo: saveButton.topAnchor, constant: -8).isActive = true
    
    // 修改placeholderLabel约束:移除固定高度,改用字体行高匹配的约束
    placeholderLabel.translatesAutoresizingMaskIntoConstraints = false
    placeholderLabel.leadingAnchor.constraint(equalTo: textView.leadingAnchor, constant: 10).isActive = true
    placeholderLabel.trailingAnchor.constraint(equalTo: textView.trailingAnchor).isActive = true
    placeholderLabel.topAnchor.constraint(equalTo: textView.topAnchor).isActive = true
    // 替换固定高度为与textView字体行高匹配的约束
    placeholderLabel.heightAnchor.constraint(equalToConstant: textView.font?.lineHeight ?? 20).isActive = true
    
    saveButton.translatesAutoresizingMaskIntoConstraints = false
    saveButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    saveButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
    saveButton.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.8).isActive = true
    saveButton.bottomAnchor.constraint(equalTo: view.keyboardLayoutGuide.topAnchor, constant: -10).isActive = true
}

2. 移除placeholderLabel的frame设置(修改setUpPlaceHolderLabel方法)

func setUpPlaceHolderLabel() {
    placeholderLabel.backgroundColor = UIColor.clear
    placeholderLabel.text = NSLocalizedString("enter text", comment: "")
    placeholderLabel.textColor = UIColor.lightGray
    placeholderLabel.font = UIFont(name: "Arial", size: 20)
    // 移除frame设置,改用AutoLayout约束控制位置
    // placeholderLabel.frame.origin = CGPoint(x: 5, y: (textView.font?.pointSize)! / 2)
}

3. 页面返回时强制更新布局(修改viewWillAppear方法)

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    textView.isScrollEnabled = true
    textView.isUserInteractionEnabled = true
    buildPriorText()
    // 强制更新布局,确保内容尺寸正确计算
    textView.layoutIfNeeded()
    // 同步placeholderLabel的隐藏状态
    placeholderLabel.isHidden = !textView.text.isEmpty
}

补充说明

  • UITextView的子视图若设置不合理约束,会干扰其内部内容布局计算,尤其是滚动相关逻辑;
  • 使用AutoLayout时,避免同时设置frame和约束,二者选其一即可;
  • 返回页面重新填充文本后,手动触发layoutIfNeeded()可确保UITextView重新计算内容尺寸,恢复滚动能力。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 19:15:59