Как сделать заголовок сборщика липким в SwiftUI 2.0

#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 внутри сборщика, но он ведет себя так, как я и предполагал. Так что мне пришлось убрать сборщик.