SwiftUI 4 iOS16中.url格式TextField处理URL行为异常
iOS 16 beta 下 TextField URL 绑定异常解答
问题(a)答复
是。iOS 16 早期beta版本(搭配Xcode 14 beta1、beta2)内置的.url ParseableFormat 格式化器存在逻辑缺陷:它内部做URL合法性判定时,会把「域名后无路径分隔符/」的输入状态判定为「用户仍在输入、URL未完成」,不会将当前文本解析为URL同步给绑定变量,只有检测到域名后的/字符时,才会触发绑定值更新,这就是观测到输入框显示内容和绑定值不同步、必须补斜杠才更新的根本原因,属于系统组件的beta版本bug,不是业务代码写法错误。
问题(b)可行解决方案
直接避开系统内置的.url格式化器即可,两种常用实现都可以完全解决这个问题:
- 方案1:用String做中间绑定层,自行处理URL转换
不直接绑定URL?类型,改为绑定实时同步的字符串状态,在输入回调中自行完成URL解析和校验,完全不受系统格式化器的逻辑限制,参考实现:
struct Editor: View { @State var data: ProfileItem @State private var linkText: String = "" init(data: ProfileItem) { self.data = data // 初始化时将已有URL转为字符串填充输入框 self._linkText = State(initialValue: data.link?.absoluteString ?? "") } var body: some View { Form { TextField("Link", text: $linkText) .keyboardType(.URL) .textInputAutocapitalization(.never) .disableAutocorrection(true) .onChange(of: linkText) { input in // 可根据业务需求自行加校验规则,比如自动补https前缀、过滤非法字符 guard let validURL = URL(string: input) else { return } data.link = validURL debugPrint("--- ", validURL) } } } }
- 方案2:自定义URL格式化器,替换系统默认实现
如果需要保留直接绑定URL?类型的写法,可以自己实现符合ParseableFormatStyle协议的URL格式化器,去掉系统默认实现里「等斜杠才判定为完整URL」的逻辑,直接基于输入字符串初始化URL即可。
补充说明:该bug在iOS 16后续的正式版本中已被苹果修复,但如果应用需要兼容iOS 16的早期测试版、或者需要更灵活的URL输入校验逻辑,优先选择上述两种自定义方案更稳妥。
内容的提问来源于stack exchange,提问作者Hardy
相关产品推荐
相关产品推荐

