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

iOS15中drawText(in:)废弃后如何更新UITextField自定义实现

iOS15+ 恢复UITextField自定义2FA字符背景功能的方案

方案1:最小改动兼容方案

  • 苹果仅将drawText(in:)标记为废弃状态,未做实际功能移除,截至iOS17版本该方法仍可正常调用,原有逻辑可以直接正常运行,仅需忽略Xcode的废弃告警即可。
  • 若需消除告警,可在重写的drawText(in:)方法前添加@available(iOS, deprecated: 15.0)标记。

方案2:官方推荐的替换实现

iOS15起官方推荐使用通用绘制方法结合文本位置API实现相同效果,替换逻辑如下:

  • 重写draw(_ rect: CGRect)方法,先调用父类实现完成基础文本绘制
  • 借助UITextPosition、UITextRange相关API获取每个字符的实际占位frame,基于该frame绘制自定义背景即可,和原有drawText(in:)中的背景绘制逻辑完全通用
  • 示例代码:
override func draw(_ rect: CGRect) {
    super.draw(rect)
    guard let text = text, !text.isEmpty else { return }
    // 遍历每个字符计算位置
    for charIndex in 0..<text.count {
        guard let startPos = position(from: beginningOfDocument, offset: charIndex),
              let endPos = position(from: startPos, offset: 1),
              let range = textRange(from: startPos, to: endPos) else { continue }
        let charFrame = firstRect(for: range)
        // 此处复用你原有绘制单个字符背景的逻辑
        let backgroundPath = UIBezierPath(roundedRect: charFrame, cornerRadius: 6)
        UIColor.systemGray5.setFill()
        backgroundPath.fill()
    }
}
  • 文本变更时调用setNeedsDisplay()触发重绘即可,可通过监听editingChanged事件实现自动触发。

方案3:跨版本稳定实现(无API依赖)

如果不想受系统API变更影响,可以换实现思路:

  • 在自定义UITextField中添加与验证码位数对应的UILabel/UIView作为单独的字符展示和背景容器
  • 隐藏原生文本显示,拦截输入事件后将字符依次赋值给对应位置的容器即可,适配所有iOS版本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 19:54:05