如何在SwiftUI 2.0中使选择器的标题粘性?

4

我想在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
        }
    }
}

似乎不可能将搜索栏与标准选择器一起使用。我最终创建了自己的选择器。 - G. Marc
1个回答

0

我无法使用Picker使其正常工作。但是我已经使用以下代码实现了相同的功能。希望这能帮到你。

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()
                }
            }
        }
    }
    }
}

类似这样的东西也是我最终得出的结论,似乎无法使用标准选择器实现。 - G. Marc
是的,我尝试在选择器中使用LazyVGrid,但它的行为并不像我想象的那样。因此,我不得不将选择器移除。 - karmjit singh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接