由于SwiftUI本机不支持macOS 11中的搜索组件,所以我正在包装NSSearchField。这主要是直到文本超出当前字段的宽度,在输入时通常会看到文本滚动。使用我的包装器不会发生这种情况,也不会使用我在网上找到的许多类似的片段。视图还不允许将光标移动到文本可见部分的末尾。
第一项是我的SearchBar,第二项是TextField。注意文本是如何在后面继续进行的(如预期的)。

import SwiftUI
struct SearchBar: NSViewRepresentable {
private var placeholder: String
@Binding var text: String
init(_ placeholder: String, text: Binding<String>) {
self.placeholder = placeholder
_text = text
}
class Coordinator: NSObject, NSSearchFieldDelegate {
@Binding var text: String
init(text: Binding<String>) {
_text = text
}
func controlTextDidChange(_ obj: Notification) {
if let searchField = obj.object as? NSSearchField {
text = searchField.stringValue
}
}
}
func makeCoordinator() -> SearchBar.Coordinator {
return Coordinator(text: $text)
}
func makeNSView(context: NSViewRepresentableContext<SearchBar>) -> NSSearchField {
let searchField = NSSearchField(frame: .zero)
searchField.delegate = context.coordinator
searchField.placeholderString = placeholder
return searchField
}
func updateNSView(_ nsView: NSSearchField, context: NSViewRepresentableContext<SearchBar>) {
nsView.stringValue = text
}
}
struct SearchBar_Previews: PreviewProvider {
@State private static var text = ""
static var previews: some View {
SearchBar("Search", text: $text)
}
}发布于 2022-09-01 22:59:12
您需要对NSSearchField进行子类化并启用isScrollable。
import SwiftUI
struct Searchbar: NSViewRepresentable {
private var placeholder: String
@Binding var text: String
init(_ placeholder: String, text: Binding<String>) {
self.placeholder = placeholder
_text = text
}
class Coordinator: NSObject, NSSearchFieldDelegate {
@Binding var text: String
init(text: Binding<String>) {
_text = text
}
func controlTextDidChange(_ obj: Notification) {
guard let searchField = obj.object as? CustomSearchField else { return }
text = searchField.stringValue
}
}
func makeCoordinator() -> Searchbar.Coordinator {
return Coordinator(text: $text)
}
func makeNSView(context: Context) -> CustomSearchField {
let searchField = CustomSearchField(frame: .zero)
// delegate
searchField.delegate = context.coordinator
// placeholder
searchField.placeholderString = placeholder
// layout
searchField.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
return searchField
}
func updateNSView(_ nsView: CustomSearchField, context: Context) {
nsView.stringValue = text
}
class CustomSearchField: NSSearchField {
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
self.cell = CustomSearchFieldCell(textCell: "")
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class CustomSearchFieldCell: NSSearchFieldCell {
override init(textCell string: String) {
super.init(textCell: string)
self.isEditable = true
self.isBordered = true
self.drawsBackground = true
self.isBezeled = true
self.isSelectable = true
self.isScrollable = true // <--- here!!
}
required init(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
}
struct SearchBar_Previews: PreviewProvider {
@State private static var text = ""
static var previews: some View {
Searchbar("Search", text: $text)
.preferredColorScheme(.light)
.frame(width: 150)
}
}https://stackoverflow.com/questions/68051361
复制相似问题