MST
星途 面试题库

面试题:SwiftUI数据流设计里如何实现父子视图间复杂数据传递与同步?

在SwiftUI中,当父视图有复杂数据结构(如嵌套字典、数组等)需要传递给子视图,并且子视图对数据的修改要实时同步回父视图时,描述你会采用哪些技术手段(如使用ObservableObject、EnvironmentObject等)来实现,并给出代码实现思路及关键代码片段。
10.7万 热度难度
编程语言Swift

知识考点

AI 面试

面试题答案

一键面试

使用ObservableObject@Binding

  1. 代码实现思路
    • 首先,定义一个符合ObservableObject协议的视图模型,在其中存储复杂数据结构。
    • 父视图将该视图模型实例传递给子视图,并使用@Binding将子视图中需要修改的数据绑定到父视图中的数据。
    • 子视图通过修改绑定的数据,自动通知父视图进行更新。
  2. 关键代码片段
import SwiftUI

// 定义一个符合ObservableObject协议的视图模型
class ComplexDataViewModel: ObservableObject {
    @Published var complexData: [String: [Int]] = ["key1": [1, 2, 3]]
}

struct ChildView: View {
    // 使用@Binding绑定父视图传递过来的数据
    @Binding var subData: [Int]
    
    var body: some View {
        Button("Modify Data") {
            subData.append(subData.count + 1)
        }
    }
}

struct ParentView: View {
    @StateObject var viewModel = ComplexDataViewModel()
    
    var body: some View {
        VStack {
            ChildView(subData: $viewModel.complexData["key1"]!)
            Text("Data in Parent: \(viewModel.complexData["key1"]!.description)")
        }
    }
}

使用EnvironmentObject

  1. 代码实现思路
    • 同样定义一个符合ObservableObject协议的视图模型来存储复杂数据结构。
    • 在父视图的environmentObject中注入该视图模型实例,这样子视图可以通过@EnvironmentObject获取到该实例。
    • 子视图对数据的修改会触发视图模型的@Published属性更新,从而使依赖该数据的所有视图(包括父视图)进行更新。
  2. 关键代码片段
import SwiftUI

// 定义一个符合ObservableObject协议的视图模型
class ComplexDataViewModel: ObservableObject {
    @Published var complexData: [String: [Int]] = ["key1": [1, 2, 3]]
}

struct ChildView: View {
    // 使用@EnvironmentObject获取父视图注入的视图模型
    @EnvironmentObject var viewModel: ComplexDataViewModel
    
    var body: some View {
        Button("Modify Data") {
            viewModel.complexData["key1"]?.append(viewModel.complexData["key1"]!.count + 1)
        }
    }
}

struct ParentView: View {
    @StateObject var viewModel = ComplexDataViewModel()
    
    var body: some View {
        VStack {
            ChildView()
               .environmentObject(viewModel)
            Text("Data in Parent: \(viewModel.complexData["key1"]!.description)")
        }
    }
}