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

Swift中触摸事件与手势共存及UITextView动态高度调整性能问题咨询

解决方案

手势与原生触摸共存实现逻辑

  • 无需移除原有pan/pinch/rotate手势,仅需实现UIGestureRecognizerDelegate的gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:代理方法,返回true即可允许手势识别器与原生触摸事件、多个手势之间同时触发,不会出现事件被拦截的问题。
  • 原有触摸事件卡顿、触发不灵敏的核心原因是自行处理全量触摸点时没有做阈值过滤、多余计算过多,且移除了系统优化过的手势识别逻辑,不需要完全改用原生触摸方法实现高度调整。

最优实现方案(无性能损耗,无事件冲突)

优先新增专属手势处理高度调整,无需触碰原生触摸方法:

  1. 在UITextView底部添加一个高度20pt的拖拽响应区域(可以是透明UIView作为拖拽把手,不影响原有UI展示)
  2. 给这个拖拽把手单独添加一个UIPanGestureRecognizer,专门用于处理高度调整逻辑
  3. 设置新手势的delegate为当前控制器,允许和原有手势共存
  4. 拖拽时仅更新UITextView的高度约束constant,实时调用父视图的layoutIfNeeded刷新布局即可

示例代码参考:

// 全局存储原始高度
var originalTextViewHeight: CGFloat = 100

// 初始化高度调整专用手势
let heightDragPan = UIPanGestureRecognizer(target: self, action: #selector(handleHeightDrag(_:)))
heightDragPan.delegate = self
dragHandleView.addGestureRecognizer(heightDragPan)

// 实现手势共存代理
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

// 高度调整逻辑
@objc func handleHeightDrag(_ gesture: UIPanGestureRecognizer) {
    let translation = gesture.translation(in: view)
    // 可自定义最小/最大高度限制
    let newHeight = max(80, min(300, originalTextViewHeight + translation.y))
    textViewHeightConstraint.constant = newHeight
    view.layoutIfNeeded()
    
    if gesture.state == .ended {
        originalTextViewHeight = newHeight
    }
}

如果你必须使用原生触摸方法实现的优化点

如果因为业务要求必须用touchesBegan/touchesMoved处理,按以下规则优化即可解决卡顿问题:

  • 仅在触摸点落在你指定的高度调整区域时才处理触摸逻辑,其余触摸事件直接调用super方法传递给原有手势识别器
  • touchesMoved中仅做高度差计算,不要执行多余的文本重绘、约束重新创建等操作,仅修改高度约束的数值
  • 增加移动阈值判断,触摸点移动超过2pt再更新高度,避免无效的高频刷新

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 17:27:00