书接上文《SwiftUI Widget IntentConfiguration》,创建可编辑的Widget,自然是要动态定义某些数据,下面就来说怎么自定义
一、定义可编辑元素
在自定义的Siri Intent Definition File
里,设置可编辑元素





这时候再次运行项目,编辑小组件

二、交互
创建 IntentHandler


选择Intents Extension
,创建

接下来勾选

注意IntentHandler的plist

代码:
- 创建model
//
// XG_WidgetData.swift
// XG_SwiftUI_3Day
//
// Created by chaowen deng on 2021/4/16.
//
import Foundation
import SwiftUI
struct AnimalModel {
let id: String
let name: String
let avatar: String
var color: Color = .white
static let panda = AnimalModel(id: "panda", name: "panda", avatar: "🐼")
static let lion = AnimalModel(id: "lion", name: "lion", avatar: "🦁️")
static let tiger = AnimalModel(id: "tiger", name: "tiger", avatar: "🐯")
static let zoo = [panda, lion, tiger]
static func animal(_ id: String, color: Choose) -> AnimalModel {
var animal: AnimalModel
switch id {
case "panda":
animal = .panda
case "lion":
animal = .lion
case "tiger":
animal = .tiger
default:
animal = AnimalModel(id: "cat", name: "cat", avatar: "🐱")
}
switch color {
case .a:
animal.color = .black
case .b:
animal.color = .blue
case .c:
animal.color = .red
case .unknown:
animal.color = .black
}
return animal
}
}
- IntentHandler修改
//
// IntentHandler.swift
// XG_IntentHandler
//
// Created by chaowen deng on 2021/4/16.
//
import Intents
class IntentHandler: INExtension, MyCustomIntentsIntentHandling {
func provideAnimalOptionsCollection(for intent: MyCustomIntentsIntent, with completion: @escaping (INObjectCollection<Animal>?, Error?) -> Void) {
let animalArr: [Animal] = AnimalModel.zoo.map { model in
Animal(identifier: model.id, display: model.name)
}
completion(INObjectCollection(items: animalArr), nil)
}
override func handler(for intent: INIntent) -> Any {
return self
}
}
- Widget修改
//
// XG_Widget.swift
// XG_Widget
//
// Created by chaowen deng on 2021/4/14.
//
import WidgetKit
import SwiftUI
struct Provider: IntentTimelineProvider {
typealias Entry = SimpleEntry
typealias Intent = MyCustomIntentsIntent
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date(), animal: .lion)
}
func getSnapshot(for configuration: Intent, in context: Context, completion: @escaping (SimpleEntry) -> Void) {
let entry = SimpleEntry(date: Date(), animal: .lion)
completion(entry)
}
func getTimeline(for configuration: Intent, in context: Context, completion: @escaping (Timeline<SimpleEntry>) -> Void) {
// Generate a timeline consisting of five entries an hour apart, starting from the current date.
let currentDate = Date()
guard let id = configuration.animal?.identifier, let entryDate = Calendar.current.date(byAdding: .minute, value: 1, to: currentDate) else {
let timeLine = Timeline(entries: [SimpleEntry(date: currentDate, animal: .lion)], policy: .atEnd)
completion(timeLine)
return
}
let entry = SimpleEntry(date: entryDate, animal: AnimalModel.animal(id, color: configuration.parameter))
let timeline = Timeline(entries: [entry], policy: .atEnd)
completion(timeline)
}
}
struct SimpleEntry: TimelineEntry {
let date: Date
let animal: AnimalModel
}
struct XG_WidgetEntryView : View {
var entry: Provider.Entry
var body: some View {
VStack {
Text(entry.animal.avatar)
.font(.largeTitle)
Text(entry.animal.name)
Text("这是颜色")
.background(entry.animal.color)
}
}
}
@main
struct XG_Widget: Widget {
let kind: String = "XG_Widget"
var body: some WidgetConfiguration {
IntentConfiguration(kind: kind, intent: MyCustomIntentsIntent.self, provider: Provider()) { entry in
XG_WidgetEntryView(entry: entry)
}
.configurationDisplayName("XG_SwiftUI_3Day")
.description("这是一个测试的widget.")
}
}
struct XG_Widget_Previews: PreviewProvider {
static var previews: some View {
XG_WidgetEntryView(entry: SimpleEntry(date: Date(), animal: .lion))
.previewContext(WidgetPreviewContext(family: .systemSmall))
}
}
效果
现在就可以编辑看到效果了,选择的列表数据由定义的AnimalModel提供,选择不同的数据,小组件展示内容会做出相应的改变
网友评论