Вопрос или проблема
Мне нужно иметь возможность стилизовать TextField в моем приложении SwiftUI для macOS. В частности, мне нужно изменить курсор (вводимый знак) и цвет выделения. Как я читал в интернете, для этого люди используют либо устаревшую и помеченную для удаления функцию .accentColor()
, либо более новую функцию .tint()
. Однако, похоже, что приложение просто игнорирует эти функции.
struct ContentView: View {
@State private var text = ""
var body: some View {
VStack {
TextField("Поле ввода текста", text: $text)
.tint(.red)
}
.padding()
}
}
Этот код создает такое окно. Как вы можете видеть, .tint(.red)
игнорируется, и используется оранжевый системный цвет акцента.
Я пробовал использовать устаревшую и помеченную для удаления .accentColor()
– это не сработало. Пытался создать пользовательский стиль для TextField и установить .tint()
/.accentColor()
там – результат тот же.
Я на macOS 14.6.1 (23G93)
и использую Xcode версии 16.0 (16A242d)
.
Я неправильно настроил проект? Или есть что-то, чего я не учел?
Ответ или решение
К сожалению, в macOS SwiftUI является более новым фреймворком, и некоторые функции, такие как изменение цвета курсора (caret) и выделения текста в TextField
, могут работать не так, как ожидается. На момент macOS 14.6.1 и Xcode 16.0 выполнение вашего кода с использованием .tint(.red)
не приводит к ожидаемым результатам, поскольку эта функция не влияет на стандартный интерфейс, используемый TextField
на macOS.
Вот несколько способов изменить цвета курсора и выделения текста в TextField
:
-
Использование .foregroundColor() для цветного текста:
Вы можете изменить цвет текста в поле ввода, но это не изменит цвет выделенного текста или курсора.struct ContentView: View { @State private var text = "" var body: some View { VStack { TextField("Текстовое поле", text: $text) .foregroundColor(.red) // Изменяет цвет текста .padding() .background(Color.white) // Для более четкого видения результата .border(Color.gray) } .padding() } }
-
Использование кастомных стилей:
Создайте свой собственный стиль дляTextField
, но имейте в виду, что это также не позволит изменить цвет выделенного текста или курсора, так как они связаны со стандартными системными настройками.struct CustomTextFieldStyle: TextFieldStyle { func _body(configuration: TextField<_Label>) -> some View { configuration .padding(10) .background(RoundedRectangle(cornerRadius: 5).stroke(Color.red, lineWidth: 1)) } } struct ContentView: View { @State private var text = "" var body: some View { VStack { TextField("Текстовое поле", text: $text) .textFieldStyle(CustomTextFieldStyle()) } .padding() } }
-
Кастомизация через NSViewRepresentable:
Если необходимо изменить цвет курсора и выделенного текста, вы можете использоватьNSViewRepresentable
для создания настраиваемого текстового поля на основе NSControl.import SwiftUI struct CustomTextField: NSViewRepresentable { @Binding var text: String func makeNSView(context: Context) -> NSTextField { let textField = NSTextField() textField.isBordered = true textField.isEditable = true textField.font = NSFont.systemFont(ofSize: 14) textField.textColor = NSColor.red // Цвет текста textField.backgroundColor = NSColor.white textField.selectable = true return textField } func updateNSView(_ nsView: NSTextField, context: Context) { nsView.stringValue = text } } struct ContentView: View { @State private var text = "" var body: some View { VStack { CustomTextField(text: $text) .frame(height: 30) } .padding() } }
Этот подход позволит вам контролировать внешний вид приложения гораздо больше, чем стандартный SwiftUI. Однако, если вы решите использовать NSViewRepresentable
, убедитесь, что вы также управляете состоянием и поведением вашего текстового поля.
Пожалуйста, следите за обновлениями документации SwiftUI и macOS, так как возможности кастомизации могут улучшаться в будущих версиях.