如何为不可编辑的UITextField仅文本区域添加点击手势识别器
实现UITextField仅文本区域响应点击
要让UITextField只有文本区域响应点击,你可以通过以下两种方案实现:
方案一:自定义UITextField重写点击判断方法
创建一个UITextField子类,重写point(inside:with:)方法,只允许文本显示范围内的点击被响应:
class TextOnlyTextField: UITextField { override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { guard let text = self.text, !text.isEmpty else { return false // 无文本时不响应点击 } let textRect = self.textRect(forBounds: self.bounds) let textSize = text.size(withAttributes: [.font: self.font ?? UIFont.systemFont(ofSize: 17)]) // 计算文本实际占据的区域 let actualTextRect = CGRect( x: textRect.origin.x, y: textRect.origin.y + (textRect.height - textSize.height)/2, width: textSize.width, height: textSize.height ) return actualTextRect.contains(point) } }
之后在TableView的Cell里替换成这个自定义TextField,原来的手势添加逻辑保持不变即可。
方案二:在自定义手势识别器中判断点击位置
如果不想替换TextField,直接修改你的CustomTapGestureRecogniser,在触摸开始时判断点击位置是否在文本区域内:
class CustomTapGestureRecogniser: UITapGestureRecognizer { var data: Int = 0 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { super.touchesBegan(touches, with: event) guard let textField = view as? UITextField, let text = textField.text, !text.isEmpty else { self.state = .failed return } if let touch = touches.first { let point = touch.location(in: textField) let textRect = textField.textRect(forBounds: textField.bounds) let textSize = text.size(withAttributes: [.font: textField.font ?? UIFont.systemFont(ofSize: 17)]) let actualTextRect = CGRect( x: textRect.origin.x, y: textRect.origin.y + (textRect.height - textSize.height)/2, width: textSize.width, height: textSize.height ) if !actualTextRect.contains(point) { self.state = .failed } } } }
当点击位置不在文本区域内时,手势识别器会直接进入failed状态,不会触发后续的openMethod方法。
注意: 如果TextField开启了adjustsFontSizeToFitWidth,需要额外适配字体缩放后的尺寸;如果文本存在换行,也要根据实际布局调整文本区域的计算逻辑。
内容的提问来源于stack exchange,提问作者Prassana Kudle
相关产品推荐
相关产品推荐

