#swiftui
#swiftui
Вопрос:
Я хочу добавить панель поиска в средство выбора в SwiftUI 2.0. Приведенный ниже демонстрационный код реализует это, но панель поиска является частью списка прокрутки, а не остается липкой вверху, когда пользователь прокручивает список. Как я могу это изменить?
import SwiftUI
import UIKit
struct ContentView: View {
@State private var selection = 0
@State private var searchText = ""
var body: some View {
NavigationView {
Form {
Picker(selection: $selection, label: Text("Picker")) {
SearchBar(text: $searchText, placeholder: "Search")
ForEach(1 ..< 21) { index in
Text(String(index)).tag(index)
}
}
}
}
}
}
struct SearchBar: UIViewRepresentable {
@Binding var text: String
var placeholder: String
func makeUIView(context: UIViewRepresentableContext<SearchBar>) -> UISearchBar {
let searchBar = UISearchBar(frame: .zero)
searchBar.delegate = context.coordinator
searchBar.placeholder = placeholder
searchBar.autocapitalizationType = .none
searchBar.searchBarStyle = .minimal
return searchBar
}
func updateUIView(_ uiView: UISearchBar, context: UIViewRepresentableContext<SearchBar>) {
uiView.text = text
}
func makeCoordinator() -> SearchBar.Coordinator {
return Coordinator(text: $text)
}
class Coordinator: NSObject, UISearchBarDelegate {
@Binding var text: String
init(text: Binding<String>) {
_text = text
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
text = searchText
}
}
}
Комментарии:
1. Кажется, что невозможно использовать панель поиска вместе со стандартным средством выбора. В итоге я создал свой собственный сборщик.
Ответ №1:
Я не мог заставить его работать с сборщиком. Но я сделал точную вещь, используя приведенный ниже код. Надеюсь, это вам поможет.
import SwiftUI
import UIKit
struct ContentView: View {
@State private var selection = 0
@State var navigateBack = false
var body: some View {
NavigationView {
Form {
NavigationLink(
destination: ItemSelectionView(selectedIndex: $selection, navigateBack: $navigateBack),
isActive: $navigateBack,
label: {
Text("Picker")
})
.overlay(
HStack {
Spacer()
Text(selection.description)
}
.padding(.trailing)
)
}
}
}
}
struct SearchBar: UIViewRepresentable {
@Binding var text: String
var placeholder: String
func makeUIView(context: UIViewRepresentableContext<SearchBar>) -> UISearchBar {
let searchBar = UISearchBar(frame: .zero)
searchBar.delegate = context.coordinator
searchBar.placeholder = placeholder
searchBar.autocapitalizationType = .none
searchBar.searchBarStyle = .minimal
return searchBar
}
func updateUIView(_ uiView: UISearchBar, context: UIViewRepresentableContext<SearchBar>) {
uiView.text = text
}
func makeCoordinator() -> SearchBar.Coordinator {
return Coordinator(text: $text)
}
class Coordinator: NSObject, UISearchBarDelegate {
@Binding var text: String
init(text: Binding<String>) {
_text = text
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
text = searchText
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct ItemSelectionView: View {
@Binding var selectedIndex: Int
@Binding var navigateBack: Bool
let columns: [GridItem] = [
GridItem(.flexible())
]
@State private var searchText = ""
var body: some View {
ScrollView {
LazyVGrid(columns: columns, alignment: .leading, pinnedViews: [.sectionHeaders ]) {
Section(header: SearchBar(text: $searchText, placeholder: "Search")) {
ForEach(1 ..< 21) { index in
HStack {
Text(String(index))
Spacer()
if selectedIndex == index
{
Image(systemName: "checkmark")
}
}
.padding(.horizontal)
.contentShape(Rectangle())
.onTapGesture {
selectedIndex = index
navigateBack.toggle()
}
Divider()
}
}
}
}
}
}
Комментарии:
1. Нечто подобное этому — это тоже то, к чему я пришел в итоге. Кажется, что это просто невозможно с помощью стандартного сборщика.
2. да, я пытался использовать LazyVGrid внутри сборщика, но он ведет себя так, как я и предполагал. Так что мне пришлось убрать сборщик.