时间:2021-05-19
首先了解下如何创建
Xcode -> File -> New -> Target 找到 Widget Extension
如果你的 Widget 支持用户配置属性,则需要勾选这个(例如天气组件,用户可以选择城市),不支持的话则不用勾选
了解下创建Widget后,系统给我们生成的文件内容
下面这个代码是没有勾选 Include Configuration Intent 的地方
Provider
Entry
官方解释: A type that specifies the date to display a widget, and, optionally, indicates the current relevance of the widget's content.
// 我的理解是就是存储小组件的数据的一个东西struct SimpleEntry: TimelineEntry { let date: Date let data: Data}PlacehodlerView
WidgetEntryView
主入口
支持多Widget样式
勾选 Include Configuration Intent 之后可能出错的地方
如果你的app中设置了 Class Prefix 这下面这个 ConfigurationIntent.self 则需要加上对应的前缀
例如前缀是 XY 则需要修改为 XYConfigurationIntent.self
@mainstruct MainWidget: Widget { private let kind: String = "MainWidget" public var body: some WidgetConfiguration { IntentConfiguration(kind: kind, intent: XYConfigurationIntent.self, provider: Provider(), placeholder: PlaceholderView()) { entry in IntentWidgetEntryView(entry: entry) } .configurationDisplayName("My Widget") .description("This is an example widget.") }}处理Widget点击事件
Widget 支持三种显示方式,分别是 systemSmall 、 systemMedium 、 systemLarge
small 样式只能用 widgetUrl 处理
medium 和 large 可以用 Link 或者 widgetUrl 处理,我们看到里面有四个相同的view,即左边图片,右边文字的,这个view代码如下(Link方式)
struct RecipeView: View { let recipe: RecipeModel var body: some View { Link(destination: URL(string: "你的网址")!) { HStack { WebImageView(imageUrl: recipe.squareImageUrl) .frame(width: 65, height: 65) Text(recipe.adjName + recipe.name) .font(.footnote) .bold() .foregroundColor(.black) .lineLimit(3) } } } }添加 Link 或 widgetUrl 后,点击每个 RecipeView 都会触发事件,这时候你需要在主项目中的 AppDelegate 中的如下方法进行处理
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { }关于Widget中加载网络图片的时机
当我们在func timeline(withcompletion)这个方法中请求到数据拿到图片链接后,必须同步把图片解析出来,否则直接让对应的WidgetView去load url 是加载不出来的
正确的写法
Struct Model { ... let image: UIImage}func timeline(with context: Context, completion: @escaping (Timeline<LFPlanEntry>) -> ()) { Network.request { data in // 解析图片 var image: UIImage? = nil if let imageData = try? Data(contentsOf: url) { image = UIImage(data: imageData) } let model = Model(image: image ?? defalutImage) // 这里给个默认图片 let entry = SimpleEntry(date: entryDate, data: model) let timeline = Timeline(entries: [entry], policy: .atEnd) completion(timeline) }}Struct WidgetView: View { let model: Model @ViewBuilder var body: some View { Image(uiImage: model.image) .resizable() }}错误的写法(直接丢url给view去加载)
struct WidgetView : View { let model: Model @State private var remoteImage : UIImage? = nil let defaultImage = UIImage(named: "default")! var body: some View { Image(uiImage: self.remoteImage ?? defaultImage) .onAppear(perform: fetchRemoteImage) } func fetchRemoteImage() { guard let url = URL(string: model.url) else { return } URLSession.shared.dataTask(with: url){ (data, response, error) in if let image = UIImage(data: data!){ self.remoteImage = image } else { print(error ?? "") } }.resume() }}基于我们的app做出来的简单效果图
Widget相关资料
Widgets
Creating a Widget Extension
Keeping a Widget Up To Date
Making a Configurable Widget
到此这篇关于详解iOS14 Widget 开发相关及易报错地方处理的文章就介绍到这了,更多相关iOS14 Widget开发内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
苹果先是发布了iOS14/iPadOS开发者预览测试版,在上周又给大家推送了iOS14/iPadOS公开测试版,iOS14界面美观,功能强大,以至于很多小伙伴都
iOS14/iPadOS14怎么升级?今天苹果面向开发人员发布了iOS14/iPadOS14开发者预览版/公开测试版Beta2,具体版本号为18A5319i,开
iOS14系统推出之后,很多人都对iOS14系统的分屏功能感到好奇。iOS14怎么分屏?iOS14有分屏功能吗?下面一起来看看吧。下面我们一起来看看iOS14究
今年的WWDC20全球开发者大会上,苹果如期推出了iOS14,并在当天放出了第一个开发者测试版本。iOS14新系统的各种新功能让人眼前一亮,冲着iOS14的新功
今天凌晨,苹果给大家推送了iOS14和iPadOS14第七个开发者测试版,距离上个测试版相隔一周的时间。iOS14beta7更新内容及升级方法:本次iOS14b