我正在寻找一个显示为简单文本单元格的字符串列表。通常,它们可能会分为“ a,b和c”部分。当他们开始搜索时,我想对它们进行不同的分组并添加更多数据,请参见“ A和B”部分。您可以将其视为在不搜索时使用更细粒度的部分,而在搜索时使用更广泛的类别。但是,当我尝试隐藏部分时,使用下面的代码,这些单元将无法在部分之间设置动画。
我经历了几次尝试,我认为生成所有可能的部分可能是最好的选择,但是当使用“ isHidden”修饰符时,我无法使动画正常工作。尝试使用和不使用此修饰符,以查看我希望实现的行为。我之前在UIKit中使用可扩散数据源完成了此操作,所以我不确定SwiftUI为何会出现问题。
我的下一个尝试是创建一个包含所有部分的中间阶段。 (a,b,c)->搜索->全部显示(a,b,c,A,B)->隐藏(A,B)
代码
import SwiftUI
struct ContentView: View {
@State var isA = true
@State var data: [String: [String]] = [
"Init Sec 1" : [
"D1.1",
"D1.2",
"D1.3"
],
"Init Sec 2" : [
"D2.1",
"D2.2",
"D2.3"
]
]
var sections: [String] {
get {
var sections = [String]()
for key in data.keys {
sections.append(key + "A")
sections.append(key + "B")
}
return sections
}
}
func getData(_ ps: String) -> [String] {
var section = ps
if isA {
if section.hasSuffix("A") {
section.removeLast()
return data[section]!
} else {
return []
}
} else {
if section.hasSuffix("B") {
section.removeLast()
return data[section]!
} else {
return []
}
}
}
var body: some View {
NavigationView {
List {
ForEach(sections, id: \.self) { section in
Section(header: Text(section)) {
ForEach(getData(section), id: \.self) { row in
Text(row)
}
}//.isHidden(getData(section).count == 0)
}
}
.animation(.default)
.navigationTitle("List Demo")
.navigationBarItems(trailing:
HStack {
Button(action: {
self.data["Sec \(nextSec)"] = [
"D\(nextSec).1",
"D\(nextSec).2",
"D\(nextSec).3"]
self.nextSec += 1
}) {
Text("Add")
}
Button(action: {
/*var sec = sections.randomElement()!
var moveSec = self.data[sec]!
var moveIdx = Int.random(in: 0..<moveSec.count)
var move = self.data[sec]!.remove(at: moveIdx)
self.data[sections.randomElement()!]!.append(move)*/
self.isA.toggle()
}) {
Text("Move")
}
}
)
}
}
}
extension View {
/// Hide or show the view based on a boolean value.
///
/// Example for visibility:
/// ```
/// Text("Label")
/// .isHidden(true)
/// ```
///
/// Example for complete removal:
/// ```
/// Text("Label")
/// .isHidden(true, remove: true)
/// ```
///
/// - Parameters:
/// - hidden: Set to `false` to show the view. Set to `true` to hide the view.
/// - remove: Boolean value indicating whether or not to remove the view.
func isHidden(_ hidden: Bool, remove: Bool = false) -> some View {
modifier(HiddenModifier(isHidden: hidden, remove: remove))
}
}
/// Creates a view modifier to show and hide a view.
///
/// Variables can be used in place so that the content can be changed dynamically.
fileprivate struct HiddenModifier: ViewModifier {
private let isHidden: Bool
private let remove: Bool
init(isHidden: Bool, remove: Bool = false) {
self.isHidden = isHidden
self.remove = remove
}
func body(content: Content) -> some View {
Group {
if isHidden {
if remove {
EmptyView()
} else {
content.hidden().frame(width: 0, height: 0).background(Color.red)
}
} else {
content
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}