Код: Выделить всё
@ViewBuilder
private var firstNameField: some View {
Group {
if viewModel.shouldShowSecureField {
// show secure field
} else {
TextField("", text: $viewModel.text, onCommit: {
isFocused = false
})
}
}
.autocorrectionDisabled()
.textContentType(.givenName)
.keyboardType(viewModel.type.keyboardType)
@ViewBuilder
private var familyNameField: some View {
Group {
if viewModel.shouldShowSecureField {
// show secure field
} else {
TextField("", text: $viewModel.text, onCommit: {
isFocused = false
})
}
}
.autocorrectionDisabled()
.textContentType(.familyName)
.keyboardType(viewModel.type.keyboardType)
}

Теперь, когда я перехожу ко второму полю, предложение больше не появляется. На первом изображении мы видим фамилию, а также я проверил свою карточку контакта + учетную запись Apple в настройках, в которой есть фамилия/фамилия.

Аналогично, для типа содержимого .emailAddress я иногда получаю предложение, а иногда оно не отображается, как, например, на моей странице входа в систему, что очень расстраивает, поскольку предложение по электронной почте появляется при сбросе пароля и создании экранов учетной записи, настроенных аналогично приведенному выше коду.
Эти текстовые поля находятся в VStack внутри представления прокрутки. Кажется, что каждый раз, когда у меня есть несколько текстовых полей, это перестает работать, но если на странице есть только одно, все работает как положено.
Есть идеи, что я могу делать неправильно?
** Обновление **
Приведенные выше изображения представляют собой созданное мной настраиваемое текстовое поле, поэтому не уверен, что что-то еще мешает этому поведению. например, когда я просто использую TextField из SwiftUI, он работает так, как ожидалось.
Вот мое настраиваемое текстовое поле:
Код: Выделить всё
import Foundation
import SwiftUI
private enum OverlayStyle {
case focus
case error
case none
}
struct TextInputField: View {
@FocusState private var isFocused: Bool
@State private var hasError: Bool = false
@ScaledMetric(wrappedValue: 1) var accessibilityScaler: CGFloat
@StateObject private var viewModel: TextInputFieldViewModel
let disabledTextColor: Color
init(viewModel: TextInputFieldViewModel, disabledTextColor: Color = AuthStyling.Colors.primaryText) {
_viewModel = StateObject(wrappedValue: viewModel)
self.disabledTextColor = disabledTextColor
}
var body: some View {
VStack(alignment: .leading, spacing: AuthStyling.Spacing.standard) {
title
input
inlineText
}
.onReceive(viewModel.isValid) { value in
hasError = !value && !isFocused
}
}
}
extension TextInputField {
private var title: some View {
Text(viewModel.title)
.font(AuthStyling.Fonts().standard)
.foregroundStyle(AuthStyling.Colors.primaryText)
}
private var input: some View {
HStack(alignment: .center) {
textField
.focused($isFocused)
.padding(.vertical, AuthStyling.Padding.textFieldVertical)
.padding(.horizontal, AuthStyling.Padding.doubleStandard)
eyeIcon
.padding(.trailing, AuthStyling.Padding.doubleStandard)
}
.frame(height: AuthStyling.Frame.element * accessibilityScaler)
.tint(AuthStyling.Colors.tint)
.background(AuthStyling.Colors.background)
.cornerRadius(AuthStyling.Border.cornerRadius)
.onChange(of: $isFocused.wrappedValue) { value in
viewModel.updateFocus(with: value)
}
.overlay {
overlayView()
}
}
@ViewBuilder
private var inlineText: some View {
if hasError {
InlineMessage(iconImageName: viewModel.errorIcon, text: viewModel.errorMessage, textColor: AuthStyling.Colors.ctaError, shouldShowIcon: true)
.padding(.bottom, AuthStyling.Padding.inline)
} else if viewModel.shouldShowPrompt {
InlineMessage(iconImageName: viewModel.promptIcon, text: viewModel.promptMessage, textColor: AuthStyling.Colors.primaryText, shouldShowIcon: false)
.padding(.bottom, AuthStyling.Padding.inline)
}
}
private func overlayView() -> some View {
let style: OverlayStyle = hasError ? .error : isFocused ? .focus : .none
var color: Color = .clear
var lineWidth = AuthStyling.Border.focusLineWidth
switch style {
case .focus:
color = AuthStyling.Colors.ctaPrimary
case .error:
color = AuthStyling.Colors.ctaError
case .none:
lineWidth = .zero
}
return RoundedRectangle(cornerRadius: AuthStyling.Border.cornerRadius)
.strokeBorder(color, lineWidth: lineWidth)
}
@ViewBuilder
private var textField: some View {
Group {
if viewModel.shouldShowSecureField {
SecureField("", text: $viewModel.text, onCommit: {
isFocused = false
})
.id(viewModel.title)
.onChange(of: viewModel.text) { _ in
viewModel.validate()
}
} else {
TextField("", text: $viewModel.text, onCommit: {
isFocused = false
})
.id(viewModel.title)
.keyboardType(viewModel.type.keyboardType)
.textContentType(viewModel.type.textContentType)
.autocorrectionDisabled()
.textInputAutocapitalization(viewModel.type.autocapitalizationType)
.disabled(viewModel.isTextFieldDisabled)
.onChange(of: viewModel.text) { _ in
viewModel.validate()
}
.foregroundColor(viewModel.isTextFieldDisabled ? disabledTextColor : AuthStyling.Colors.primaryText)
}
}
.font(AuthStyling.Fonts().regular)
.foregroundStyle(AuthStyling.Colors.primaryText)
.background(AuthStyling.Colors.background)
}
@ViewBuilder
private var eyeIcon: some View {
if viewModel.shouldShowEyeIcon {
Button(action: {
viewModel.eyeIconTapped()
}, label: {
Image(viewModel.eyeIcon)
})
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/790 ... in-swiftui
Мобильная версия