JSON 文件中的 SwiftUI 搜索列表
Posted
技术标签:
【中文标题】JSON 文件中的 SwiftUI 搜索列表【英文标题】:SwiftUI search list from JSON file 【发布时间】:2020-04-08 12:23:46 【问题描述】:目前我的SearchView
在数组names
上使用了一个简单的过滤器,我需要它来让它通过我的JSON 文件进行搜索。我有一个具有这种结构的 JSON 文件:
struct UcmData: Codable, Identifiable
let id: Int
let building: [Building]
// MARK: - Building
struct Building: Codable, Identifiable
let id: Int
let title, subtitle, info, image: String
let floor: [Floor]
// MARK: - Floor
struct Floor: Codable, Identifiable
let id, number: Int
let title, subtitle, image: String
let cabinet: [Cabinet]?
// MARK: - Cabinet
struct Cabinet: Codable, Identifiable
let id: Int
let number: String
let person: [Person]
// MARK: - Person
struct Person: Codable, Identifiable
let id: Int
let name: String
搜索视图:
struct SearchView: View
let names = ["306 B", "doc. Ing. Michal Čerňanský, PhD."]
let ucmData = Bundle.main.decode(UcmData.self, from: "ucm_data.json")
@State private var searchText = ""
@State private var showCancelButton: Bool = false
var body: some View
VStack
HStack
HStack
Image(systemName: "magnifyingglass")
TextField("Zadajte text pre vyhľadávanie", text: $searchText, onEditingChanged: isEditing in
self.showCancelButton = true
, onCommit:
print("onCommit")
).foregroundColor(.primary)
Button(action:
self.searchText = ""
)
Image(systemName: "xmark.circle.fill").opacity(searchText == "" ? 0 : 1)
.padding(EdgeInsets(top: 8, leading: 6, bottom: 8, trailing: 6))
.foregroundColor(.secondary)
.background(Color(.secondarySystemBackground))
.cornerRadius(10.0)
if showCancelButton
Button("Cancel")
UIApplication.shared.endEditing(true)
self.searchText = ""
self.showCancelButton = false
.foregroundColor(Color(.systemBlue))
.padding(.horizontal)
.navigationBarHidden(showCancelButton)
List
ForEach(self.names.filter
self.searchText.isEmpty ? $0.localizedStandardContains("") :
$0.localizedStandardContains(self.searchText)
, id: \.self) name in
Text(name)
.navigationBarTitle(Text("Vyhľadávanie"))
.resignKeyboardOnDragGesture()
extension UIApplication
func endEditing(_ force: Bool)
self.windows
.filter$0.isKeyWindow
.first?
.endEditing(force)
struct ResignKeyboardOnDragGesture: ViewModifier
var gesture = DragGesture().onChanged_ in
UIApplication.shared.endEditing(true)
func body(content: Content) -> some View
content.gesture(gesture)
extension View
func resignKeyboardOnDragGesture() -> some View
return modifier(ResignKeyboardOnDragGesture())
struct SearchView_Previews: PreviewProvider
static var previews: some View
Group
SearchView()
.environment(\.colorScheme, .light)
SearchView()
.environment(\.colorScheme, .dark)
如何使searchText
与Cabinet.number
或Person.name
匹配,并在JSON 文件中列出匹配项目及其路径,例如“building.title > floor.title > cabinet.number”或对于人“building.title > floor.title > cabinet.number > person.name”?谢谢你的建议。
【问题讨论】:
【参考方案1】:不完全确定,但我假设搜索字段可以包含人名或内阁编号,您希望根据这些名称过滤数据集并以时尚的方式显示列表:
building.title > floor.title > cabinet.number
或
building.title > floor.title > cabinet.number > person.name
也许这些方面的东西可能会有所帮助:
struct ContentView: View
let data: UcmData
@State var searchString = ""
var found: [String]
var result = [String]()
data.building.forEach (building) in //go through every building
building.floor.forEach (floor) in //go through every floor
floor.cabinet?.forEach (cabinet) in //go through every cabinet
var cabinetFound: String
return "\(building.title) > \(floor.title) > \(cabinet.number)"
if cabinet.number == searchString //check with cabinet [!]
result.append(cabinetFound) //add search result
else
cabinet.person.forEach (person) in //go through every person
if person.name == searchString //check with person [!]
let personFound = cabinetFound + " > \(person.name)"
result.append(personFound) //add search result
return result
var body: some View
VStack
TextField("search string", text: $searchString) //search field
List(found, id: \.self) (current) in //List of search results
Text(current)
*此示例只是您视图的子集,仅展示搜索功能。如果有意义就整合它。
found
是 String
的 Array
,将在请求时计算
当搜索字段更新时,searchString
更新并重新渲染正文,这将使用 found
中的元素刷新 List
我希望这会有所帮助:)
【讨论】:
非常感谢!我不知道如何编写您创建的var found
,我所需要的只是实现您的代码并替换if cabinet.number == searchString
以及person.name
的条件if cabinet.number.localizedStandardContains(searchString)
,使其更像“全文搜索”,例如,因为我希望搜索列出所有可能的匹配项,而不仅仅是搜索时正确键入的那个。然后它就像一个魅力,再次感谢你!以上是关于JSON 文件中的 SwiftUI 搜索列表的主要内容,如果未能解决你的问题,请参考以下文章
自学IOS开发第3天·基础SwiftUI之动态滑动列表(上)
自学IOS开发第3天·基础SwiftUI之动态滑动列表(上)
如何将 csv 文件读入 SWI prolog 中的列表列表,其中内部列表代表 CSV 的每一行?