Textfield 在 iOS 17 中忽略 Binding 的 getter 值

问题描述 投票:0回答:1

在下面的示例中,无论如何修改

userPhoneNumber
,显示的
Textfield's
值都会保持不变,就好像绑定的 getter 值被忽略一样。

@Binding var userPhoneNumber: String

var body: some View {
     TextField("", text: Binding(get: {
            userPhoneNumber
        }, set: { value in
            let containsOnlyDigits = value.allSatisfy("0123456789".contains)
            
            guard containsOnlyDigits else {
                return
            }
            
            userPhoneNumber = value
        }))
}

我已放置日志并确认每次都会调用 getter 并且

userPhoneNumber
具有正确的值。

考虑到这一点,可以公平地假设传递常量绑定仍然允许用户修改

Textfield

struct ContentView: View {
    @State private var value: Binding<String> = .constant("1")
    
    var body: some View {
        VStack {
            TextField("", text: value)
        }
    }
}

运行此示例可确认文本字段的输入已被用户修改,即使在模拟器为 iOS 17+ 的情况下传递的绑定是恒定的。在 iOS 17+ 的设备上测试它会复制与模拟器相同的行为。

然而,iOS 16 模拟器并非如此,我敢打赌,运行 iOS 16 的设备上也不会出现这种情况。

如何在 iOS 17 中强制

TextField
尊重绑定的 getter?

swift swiftui binding
1个回答
0
投票

您可以使用

.onChange
尝试不同的方法, 仅在文本字段中显示数字。

示例代码:

struct ContentView: View {
    @State private var value = "1"
    
    var body: some View {
        VStack (spacing: 55) {
            Text(value) // <-- for testing
            TestingView(userPhoneNumber: $value)
        }
    }
}

struct TestingView: View {
    @Binding var userPhoneNumber: String
    
    var body: some View {
        TextField("", text: $userPhoneNumber)
            .border(.red)
            .onChange(of: userPhoneNumber) { old, new in
                if new.allSatisfy("0123456789".contains) {
                    userPhoneNumber = new
                } else {
                    userPhoneNumber = old
                }
            }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.