SwiftUI:从 macOS TextField 中删除 'Focus Ring' 突出显示边框
SwiftUI: Remove 'Focus Ring' Highlight Border from macOS TextField
我使用以下代码在 SwiftUI 中创建了自定义搜索栏。它在 iOS / Catalyst:
上运行良好
...但是当 运行 在 macOS 上原生时,'focus ring' 突出显示的边框样式(当用户选择文本字段时)反而会破坏效果:
使用 .textFieldStyle(PlainTextFieldStyle())
已从基础字段(我认为是 NSTextField
)中删除了大部分默认样式,但 不是 聚焦环.
有没有办法删除它?我尝试创建一个自定义 TextFieldStyle
并应用它,但找不到任何修饰符来设置该边框的样式。
public struct SearchTextView: View {
@Binding var searchText: String
#if !os(macOS)
private let backgroundColor = Color(UIColor.secondarySystemBackground)
#else
private let backgroundColor = Color(NSColor.controlBackgroundColor)
#endif
public var body: some View {
HStack {
Spacer()
#if !os(macOS)
Image(systemName: "magnifyingglass")
#else
Image("icons.general.magnifyingGlass")
#endif
TextField("Search", text: self.$searchText)
.textFieldStyle(PlainTextFieldStyle())
.foregroundColor(.primary)
.padding(8)
Spacer()
}
.foregroundColor(.secondary)
.background(backgroundColor)
.cornerRadius(12)
.padding()
}
public init(searchText: Binding<String>) {
self._searchText = searchText
}
}
如 Asperi to a similar question 的回答所述,(目前)无法使用 SwiftUI 关闭特定区域的聚焦环;但是,以下解决方法将禁用应用程序中所有 NSTextField
个实例的对焦环:
extension NSTextField {
open override var focusRingType: NSFocusRingType {
get { .none }
set { }
}
}
如果你想在视图中用你自己的自定义焦点环替换它,onEditingChanged
参数可以帮助你实现这一点(见下面的例子);然而,不幸的是,当用户键入第一个字母时,它会在 macOS 上被调用,而不是当他们第一次单击该字段时(这并不理想)。
理论上,您可以在 focusable
修饰符中使用 onFocusChange
闭包,但目前这些 macOS 文本字段似乎不会被调用(从 macOS 10.15.3 开始) ).
public struct SearchTextView: View {
@Binding var searchText: String
@State private var hasFocus = false
#if !os(macOS)
private var backgroundColor = Color(UIColor.secondarySystemBackground)
#else
private var backgroundColor = Color(NSColor.controlBackgroundColor)
#endif
public var body: some View {
HStack {
Spacer()
#if !os(macOS)
Image(systemName: "magnifyingglass")
#else
Image("icons.general.magnifyingGlass")
#endif
TextField("Search", text: self.$searchText, onEditingChanged: { currentlyEditing in
self.hasFocus = currentlyEditing // If the editing state has changed to be currently edited, update the view's state
})
.textFieldStyle(PlainTextFieldStyle())
.foregroundColor(.primary)
.padding(8)
Spacer()
}
.foregroundColor(.secondary)
.background(backgroundColor)
.cornerRadius(12)
.border(self.hasFocus ? Color.accentColor : Color.clear, width: self.hasFocus ? 3 : 0)
.padding()
}
public init(searchText: Binding<String>) {
self._searchText = searchText
}
}
我使用以下代码在 SwiftUI 中创建了自定义搜索栏。它在 iOS / Catalyst:
上运行良好...但是当 运行 在 macOS 上原生时,'focus ring' 突出显示的边框样式(当用户选择文本字段时)反而会破坏效果:
使用 .textFieldStyle(PlainTextFieldStyle())
已从基础字段(我认为是 NSTextField
)中删除了大部分默认样式,但 不是 聚焦环.
有没有办法删除它?我尝试创建一个自定义 TextFieldStyle
并应用它,但找不到任何修饰符来设置该边框的样式。
public struct SearchTextView: View {
@Binding var searchText: String
#if !os(macOS)
private let backgroundColor = Color(UIColor.secondarySystemBackground)
#else
private let backgroundColor = Color(NSColor.controlBackgroundColor)
#endif
public var body: some View {
HStack {
Spacer()
#if !os(macOS)
Image(systemName: "magnifyingglass")
#else
Image("icons.general.magnifyingGlass")
#endif
TextField("Search", text: self.$searchText)
.textFieldStyle(PlainTextFieldStyle())
.foregroundColor(.primary)
.padding(8)
Spacer()
}
.foregroundColor(.secondary)
.background(backgroundColor)
.cornerRadius(12)
.padding()
}
public init(searchText: Binding<String>) {
self._searchText = searchText
}
}
如 Asperi to a similar question NSTextField
个实例的对焦环:
extension NSTextField {
open override var focusRingType: NSFocusRingType {
get { .none }
set { }
}
}
如果你想在视图中用你自己的自定义焦点环替换它,onEditingChanged
参数可以帮助你实现这一点(见下面的例子);然而,不幸的是,当用户键入第一个字母时,它会在 macOS 上被调用,而不是当他们第一次单击该字段时(这并不理想)。
理论上,您可以在 focusable
修饰符中使用 onFocusChange
闭包,但目前这些 macOS 文本字段似乎不会被调用(从 macOS 10.15.3 开始) ).
public struct SearchTextView: View {
@Binding var searchText: String
@State private var hasFocus = false
#if !os(macOS)
private var backgroundColor = Color(UIColor.secondarySystemBackground)
#else
private var backgroundColor = Color(NSColor.controlBackgroundColor)
#endif
public var body: some View {
HStack {
Spacer()
#if !os(macOS)
Image(systemName: "magnifyingglass")
#else
Image("icons.general.magnifyingGlass")
#endif
TextField("Search", text: self.$searchText, onEditingChanged: { currentlyEditing in
self.hasFocus = currentlyEditing // If the editing state has changed to be currently edited, update the view's state
})
.textFieldStyle(PlainTextFieldStyle())
.foregroundColor(.primary)
.padding(8)
Spacer()
}
.foregroundColor(.secondary)
.background(backgroundColor)
.cornerRadius(12)
.border(self.hasFocus ? Color.accentColor : Color.clear, width: self.hasFocus ? 3 : 0)
.padding()
}
public init(searchText: Binding<String>) {
self._searchText = searchText
}
}