SwiftData使用静态数据预览视图
SwiftData使用静态数据预览视图

SwiftData使用静态数据预览视图

在SwiftData使用过程中,通过使用测试数据快速预览视图。下面将讲述如何使用静态数据预览SwiftData数据。

下面是一个SwiftData文件代码:

import SwiftUI
import SwiftData
import MapKit

@Model
class Place {
    
    @Attribute(.unique) var name: String
    var latitude: Double
    var longitude: Double
    var interested: Bool
    
    var location: CLLocationCoordinate2D {
        CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
    }
    
    var image: Image {
        Image(name.lowercased().replacingOccurrences(of: " ", with: ""))
    }
    
    init(name: String, latitude: Double, longitude: Double, interested: Bool) {
        self.name = name
        self.latitude = latitude
        self.longitude = longitude
        self.interested = interested
    }
}

静态数据

创建两个静态变量,一个管理实例的数组,另一个则提供一个预览的ModelContainer,利用数组的轮训将实例插入到该ModelContainer中。

在视图文件中,绑定该ModelContainer,从而实现对于测试数据的预览。

1、previewPlaces

在SwiftData文件中新增静态数据previewPlaces变量:

static var previewPlaces: [Place] {
    [
        Place(name: "Bellagio", latitude: 36.1129, longitude: -115.1765, interested: true),
        Place(name: "Paris", latitude: 36.1125, longitude: -115.1707, interested: true),
        Place(name: "Treasure Island", latitude: 36.1247, longitude: -115.1721, interested: true)
    ]
}

作用: 提供一个数组,包含一些示例 Place 数据,用于在开发和预览时使用。

内容: 包含多个 Place 实例,每个实例具有特定的名称、经纬度、以及是否感兴趣 (interested) 的属性值。

用途: 开发者可以在 UI 预览中使用这些静态数据来快速测试和查看视图的布局和功能,而无需连接到实际的数据源。

2、preview

创建一个临时的ModelContainer容器:

@MainActor
    static var preview: ModelContainer {
        let container = try! ModelContainer(for: Place.self, configurations: ModelConfiguration(isStoredInMemoryOnly: true))
        for place in previewPlaces {
            container.mainContext.insert(place)
        }
        return container
}

作用: 提供一个 ModelContainer 实例,并将 previewPlaces 数据插入其中,用于 SwiftUI 的预览功能。

内容:

创建一个只存储在内存中的 ModelContainer。

将 previewPlaces 数据插入到容器的 mainContext 中。

用途: 让开发者可以在视图预览中使用 SwiftData 的功能,模拟真实的数据存储和查询。

两者的关系

1、previewPlaces 是一个简单的静态数据数组,用来模拟实际的 Place 数据。

2、priview 利用 previewPlaces 数据,创建了一个完整的 ModelContainer,以支持更复杂的预览场景(如使用 SwiftData 的查询和存储功能)。

实际应用

在View中,通过给#Preview的View绑定modelContainer,实现通过静态数据预览视图。

import SwiftUI
import SwiftData

struct PlaceList: View {
    @Query(sort:\Place.name) private var places: [Place]
    var body: some View {
        List(places) { place in
            place.image
                .resizable()
        }
    }
}

#Preview {
    PlaceList()
        .modelContainer(Place.preview)
}

注意,这里的modelContainer后面直接使用Place.preview,而不是使用modelContainer(for:)绑定容器。

最后,实际的预览效果为:

相关文章

1、iOS 18, SwiftUI 6, & Swift 6: 从零开始构建iOS应用程序, 涵盖visionOS, macOS, watchOS:https://www.bilibili.com/video/BV1b6421f7Px?spm_id_from=333.788.player.switch&vd_source=f21219cb93118beac6a36b0ef961df6a&p=7

2、SwiftData预览报错问题:https://fangjunyu.com/2024/11/04/swiftdata-%e9%a2%84%e8%a7%88%e6%8a%a5%e9%94%99%e9%97%ae%e9%a2%98/

完整代码

PlaceList视图

import SwiftUI
import SwiftData

struct PlaceList: View {
    @Query(sort:\Place.name) private var places: [Place]
    var body: some View {
        List(places) { place in
            place.image
                .resizable()
        }
    }
}

#Preview {
    PlaceList()
        .modelContainer(Place.preview)
}

Place文件

import SwiftUI
import SwiftData
import MapKit

@Model
class Place {
    
    @Attribute(.unique) var name: String
    var latitude: Double
    var longitude: Double
    var interested: Bool
    
    var location: CLLocationCoordinate2D {
        CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
    }
    
    var image: Image {
        Image(name.lowercased().replacingOccurrences(of: " ", with: ""))
    }
    
    init(name: String, latitude: Double, longitude: Double, interested: Bool) {
        self.name = name
        self.latitude = latitude
        self.longitude = longitude
        self.interested = interested
    }
    
    @MainActor
    static var preview: ModelContainer {
        let container = try! ModelContainer(for: Place.self, configurations: ModelConfiguration(isStoredInMemoryOnly: true))
        for place in previewPlaces {
            container.mainContext.insert(place)
        }
        return container
    }
    
    static var previewPlaces: [Place] {
        [
            Place(name: "Bellagio", latitude: 36.1129, longitude: -115.1765, interested: true),
            Place(name: "Paris", latitude: 36.1125, longitude: -115.1707, interested: true),
            Place(name: "Treasure Island", latitude: 36.1247, longitude: -115.1721, interested: true),
            Place(name: "Stratosphere", latitude: 36.1475, longitude: -115.1566, interested: true),
            Place(name: "Luxor", latitude: 36.0955, longitude: -115.1761, interested: true),
            Place(name: "Excalibur", latitude: 36.0988, longitude: -115.1754, interested: true)
        ]
    }
}

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开放者。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注