返回

SwiftUI 100 天第 5 部分:ObservableObject 中的 Corner

IOS

SwiftUI 中的 Corner:ObservableObject

在 [SwiftUI 100 天第 4 部分](链接至第 4 部分的文章)中,我们研究了如何在 SwiftUI 中使用 CornerShape 创建自定义形状。在本部分中,我们将更深入地探讨 Corner,并介绍如何使用 @Published 属性包装器和 ObservableObject 协议来改善代码可读性,同时维护 Codable 协议支持。

重新审视 CornerShape

让我们快速回顾一下 CornerShape。它允许我们在 SwiftUI 中创建带有圆角的自定义形状。我们使用 corners() 修饰器指定要舍入的角,并提供一个 radius 参数来指定舍入半径。

struct MyShape: Shape {
    func path(in rect: CGRect) -> Path {
        var path = Path()
        path.addRoundedRect(in: rect, cornerRadius: 20)
        return path
    }
}

使用 ObservableObject 改进代码可读性

在 SwiftUI 100 天第 4 部分中,我们通过在 Order 模型中使用 @State 属性包装器来存储订单数据。但是,当我们需要在多屏之间共享数据时,@State 并不理想,因为它的作用域仅限于当前视图。

ObservableObject 协议为我们提供了一种在视图层次结构中共享状态的更好方法。它使我们能够定义一个包含可观察状态的类,然后将其作为环境对象注入视图。这允许我们访问共享状态,而无需在每个视图中显式传递它。

要使用 ObservableObject,我们需要创建遵循该协议的类。该类包含我们想要共享的状态属性,并且这些属性需要标记为 @Published

class Order: ObservableObject {
    @Published var items: [Item]
    @Published var total: Double
}

接下来,我们在内容视图中注入 Order 环境对象。

struct ContentView: View {
    @EnvironmentObject var order: Order
    
    var body: some View {
        // 访问共享状态
    }
}

维护 Codable 协议支持

值得注意的是,当我们在 Order 类中使用 @Published 时,我们失去了自动的 Codable 协议支持。这是因为 @Published 属性包装器会生成一个私有属性,该属性不会被编码或解码。

为了解决这个问题,我们可以手动实现 Codable 协议,或使用第三方库(例如 CodableWrapper)来简化该过程。

结论

使用 ObservableObject 协议,我们可以改进 SwiftUI 中代码的可读性,同时维护 Codable 协议支持。这使我们能够在视图层次结构中轻松共享状态,并避免了使用 @State 属性包装器的限制。通过拥抱 ObservableObject 的强大功能,我们可以编写更清晰、更可维护的 SwiftUI 代码。