[英]SwiftUI - Dynamic List filtering animation flies to right side when data source is empty
我有一個List
,它從我的people
數組中獲取數據並顯示他們的姓名。
我還在過濾列表,使其僅顯示包含文本字段文本的名稱,即searchText
。 這是我的代碼:
struct Person: Identifiable {
let id = UUID() /// required for the List
var name = ""
}
struct ContentView: View {
@State var searchText = ""
var people = [ /// the data source
Person(name: "Alex"),
Person(name: "Ally"),
Person(name: "Allie"),
Person(name: "Bob"),
Person(name: "Tim"),
Person(name: "Timothy")
]
var body: some View {
VStack {
TextField("Search here", text: $searchText) /// text field
.padding()
List {
ForEach(
people.filter { person in /// filter the people
searchText.isEmpty || person.name.localizedStandardContains(searchText)
}
) { person in
Text(person.name)
}
}
.animation(.default) /// add the animation
}
}
}
如果沒有.animation(.default)
,它不會為更改設置動畫(如預期的那樣)。
使用.animation(.default)
,它會動畫!
但是,當人名都不包含searchText
時,就會出現問題。 發生這種情況時, people.filter
返回一個空數組, List
就會崩潰。 例如,當我輸入“q”時,會發生這種情況:
整個列表飛到右邊,當我刪除“q”時從左邊放大。 我怎樣才能防止這種情況發生? 我正在尋找與正常過濾 animation 類似的 animation(向上滑動並消失,就像在第二個 gif 中一樣),或者只是淡出它。
我剛剛在 iOS 13 上進行了測試,如果我刪除.animation(.default)
,它可以完美運行!
但是,如果我再次添加.animation(.default)
,我會得到與 iOS 14 中相同的結果。
我的實際代碼對人員進行了分組,因此我已經使用了List
中的sections
。
struct Group: Identifiable {
let id = UUID() /// required for the List
var groupName = ""
var people = [Person]()
}
struct Person: Identifiable {
let id = UUID() /// required for the List
var name = ""
}
struct ContentView: View {
@State var searchText = ""
/// groups of people
var groups = [
Group(groupName: "A People", people: [
Person(name: "Alex"),
Person(name: "Ally"),
Person(name: "Allie")
]),
Group(groupName: "B People", people: [
Person(name: "Bob")
]),
Group(groupName: "T People", people: [
Person(name: "Tim"),
Person(name: "Timothy")
])
]
var body: some View {
VStack {
TextField("Search here", text: $searchText) /// text field
.padding()
List {
ForEach(
/// Filter the groups for people that match searchText
groups.filter { group in
searchText.isEmpty || group.people.contains(where: { person in
person.name.localizedStandardContains(searchText)
})
}
) { group in
Section(header: Text(group.groupName)) {
ForEach(
/// filter the people in each group
group.people.filter { person in
searchText.isEmpty || person.name.localizedStandardContains(searchText)
}
) { person in
Text(person.name)
}
}
}
}
.animation(.default) /// add the animation
}
}
}
如果我按照@mahan 的建議將ForEach
包裝在List
中,則會發生這種情況:
List
動畫完美,沒有奇怪的縮放 animation,但節標題失去了 styles 並且看起來像正常行。 但我認為我們正在接近!
將ForEach包裝在Section中,問題將得到解決。
List {
Section {
ForEach(
people.filter { person in /// filter the people
searchText.isEmpty || person.name.localizedStandardContains(searchText)
}
) { person in
Text(person.name)
}
}
}
.animation(.default) /// add the animation
您可以根據需要添加任意數量的部分。
struct Person: Identifiable {
let id = UUID() /// required for the List
var name = ""
}
struct ContentView: View {
@State var searchText = ""
var people = [ /// the data source
Person(name: "Alex"),
Person(name: "Ally"),
Person(name: "Allie"),
Person(name: "Bob"),
Person(name: "Tim"),
Person(name: "Timothy")
]
var people2 = [ /// the data source
Person(name: "John"),
Person(name: "George"),
Person(name: "Jack"),
Person(name: "Mike"),
Person(name: "Barak"),
Person(name: "Steve")
]
var body: some View {
VStack {
TextField("Search here", text: $searchText) /// text field
.padding()
List {
Section {
ForEach(
people.filter { person in /// filter the people
searchText.isEmpty || person.name.localizedStandardContains(searchText)
}
) { person in
Text(person.name)
}
}
Section {
ForEach(people2.filter { person in /// filter the people
searchText.isEmpty || person.name.localizedStandardContains(searchText)
}) { person in
Text(person.name)
}
}
}
.animation(.default) /// add the animation
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.