Swiftui 如何编辑子类对象列表
我有一个从同一个类派生的不同类的项目列表 目标:使用不同的视图编辑任何对象 模型:Swiftui 如何编辑子类对象列表,swiftui,Swiftui,我有一个从同一个类派生的不同类的项目列表 目标:使用不同的视图编辑任何对象 模型: class Paper: Hashable, Equatable { var name: String var length: Int init() { name = "" length = 0 } init(name: String, length: Int) { self.name = name
class Paper: Hashable, Equatable {
var name: String
var length: Int
init() {
name = ""
length = 0
}
init(name: String, length: Int) {
self.name = name
self.length = length
}
static func == (lhs: Paper, rhs: Paper) -> Bool {
return lhs.length == rhs.length
}
func hash(into hasher: inout Hasher) {
hasher.combine(length)
}
}
class ScientificPaper: Paper {
var biology: Bool
override init(name: String, length: Int) {
biology = false
super.init(name: name, length: length)
}
}
class TechnicalPaper: Paper {
var electronics: Bool
override init(name: String, length: Int) {
electronics = false
super.init(name: name, length: length)
}
}
包含列表的主视图
struct TestView: View {
@Binding var papers: [Paper]
@State private var edit = false
@State private var selectedPaper = Paper()
var body: some View {
let scientificBinding = Binding<ScientificPaper>(
get: {selectedPaper as! ScientificPaper},
set: { selectedPaper = $0 }
)
VStack {
List {
ForEach(papers, id: \.self) { paper in
HStack {
Text(paper.name)
Text("\(paper.length)")
Spacer()
Button("Edit") {
selectedPaper = paper
edit = true
}
}
}
}
}
.sheet(isPresented: $edit) {
VStack {
if selectedPaper is ScientificPaper {
ScientificForm(paper: scientificBinding)
}
if selectedPaper is TechnicalPaper {
TechnicalForm(paper: technicalBinding)
}
}
}
}
}
问题是,在运行时,我得到以下结果:
无法将“Paper”类型的值强制转换为“ScientificPaper”
可能是因为所选纸张已初始化为纸张
编辑属于不同类别的列表项的正确策略是什么?该错误是由于在
正文中创建了绑定,该绑定在每次刷新时计算,因此绑定无效
解决方案是将绑定作为可计算属性,因此只有在正确的流中进行验证后才请求它
使用Xcode 12.1/iOS 14.1进行测试(演示用于scientificBinding
仅为简单起见)
struct TestView:View{
@装订文件:[文件]
@国家私有变量编辑=false
@国家私有变量selectedPaper=Paper()
var scientificBinding:Binding{//谢谢Asperi。'错误是由于在body'中创建绑定造成的,这就是问题所在。另一个选项是在调用表单之前创建绑定:let sb=Binding(get:{selectedPaper as!ScientificPaper},set:{selectedPaper=$0})科学形式(论文编号:sb)
struct ScientificForm: View {
@Binding var paper: ScientificPaper
var body: some View {
Form {
Text("Scientific")
TextField("Name: ", text: $paper.name)
TextField("Length: ", value: $paper.length, formatter: NumberFormatter())
TextField("Biology: ", value: $paper.biology, formatter: NumberFormatter())
}
}
}
struct TechnicalForm: View {
@Binding var paper: TechnicalPaper
var body: some View {
Form {
Text("Technical")
TextField("Name: ", text: $paper.name)
TextField("Length: ", value: $paper.length, formatter: NumberFormatter())
TextField("Electronics: ", value: $paper.electronics, formatter: NumberFormatter())
}
}
}
struct TestView: View {
@Binding var papers: [Paper]
@State private var edit = false
@State private var selectedPaper = Paper()
var scientificBinding: Binding<ScientificPaper> { // << here !!
return Binding<ScientificPaper>(
get: {selectedPaper as! ScientificPaper},
set: { selectedPaper = $0 }
)
}
var body: some View {
VStack {
List {
ForEach(papers, id: \.self) { paper in
HStack {
Text(paper.name)
Text("\(paper.length)")
Spacer()
Button("Edit") {
selectedPaper = paper
edit = true
}
}
}
}
}
.sheet(isPresented: $edit) {
VStack {
if selectedPaper is ScientificPaper {
ScientificForm(paper: scientificBinding)
}
// if selectedPaper is TechnicalPaper {
// TechnicalForm(paper: technicalBinding)
// }
}
}
}
}