我正在尝试开发一个用户必须输入姓名的视图。这两个文本字段有一个 FocusState。一切都很顺利,当焦点改变他的目标时,就不会出现一点反弹。
我不知道我的代码中发生了什么问题。 这是我的代码:
struct OnboardingViewPart2: View {
enum Field: Hashable{
case name
case surname
}
@State var displayName = ""
@State var showImagePicker = false
@State var isSomePhotoSelected = false
@State var displaySurname = ""
@FocusState var focusedField : Field?
// For image picker
@State var imageSelected: UIImage = UIImage(systemName: "person.fill")!
@State var sourceType: UIImagePickerController.SourceType = .photoLibrary
var body: some View {
VStack(alignment: .center, spacing: 20, content: {
//其他代码
// MARK: Textfield group
Group{
TextField("Add your name here...", text: $displayName)
.padding()
.frame(height: 60)
.frame(maxWidth: .infinity)
.background(Color.MyTheme.beige)
.cornerRadius(12)
.font(.headline)
.autocapitalization(.sentences)
.padding(.horizontal)
.focused($focusedField, equals: .name)
TextField("Add your surname here...", text: $displaySurname)
.padding()
.frame(height: 60)
.frame(maxWidth: .infinity)
.background(Color.MyTheme.beige)
.cornerRadius(12)
.font(.headline)
.autocapitalization(.sentences)
.padding(.horizontal)
.focused($focusedField, equals: .surname)
}
.onSubmit {focusedField = focusedField == .name ? .surname : nil}
//other code
}) // VStack
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.MyTheme.purple)
//.edgesIgnoringSafeArea(.all)
.sheet(isPresented: $showImagePicker, content: {
ImagePicker(imageSelected: $imageSelected, sourceType: $sourceType, isSomeImageSelected: $isSomePhotoSelected)
}) // Picker
}
}
//已更新!!
也许有点太晚了,但我刚刚遇到这个问题并找到了一个适合我的解决方案。
class TextFieldDelegate: NSObject, UITextFieldDelegate {
var shouldReturn: (() -> Bool)?
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if let shouldReturn = shouldReturn {
return shouldReturn()
}
else {
return true
}
}
}
然后在我的 SwiftUI 视图中:
import Introspect
struct TestView: View {
enum FocusedField {
case username, password
}
@State private var username: String = ""
@State private var password: String = ""
var usernameFieldDelegate = TextFieldDelegate()
var passwordFieldDelegate = TextFieldDelegate()
@FocusState private var focusedField: FocusedField?
var body: some View {
VStack {
TextField(text: $username)
.focused($focusedField, equals: .username)
.introspectTextField(customize: { textField in
usernameFieldDelegate.shouldReturn = {
if usernameIsValid() {
focusedField = .password
}
return false
}
textField.delegate = usernameFieldDelegate
})
SecureField(text: $password)
.focused($focusedField, equals: .password)
.introspectTextField(customize: { textField in
passwordFieldDelegate.shouldReturn = {
validateAndProceed()
return false
}
textField.delegate = passwordFieldDelegate
})
}
}
func usernameIsValid() -> Bool {
return true
}
func validateAndProceed() {}
}