引言

  经过前面几篇文章阅读,已经掌握开发一款小组件的基本技能了,接下来开始掌握一些相对高级一点的技能。本文创建一个可配置小组件,通过修改时间类型,让Text空间显示不同格式的时间。

本文大纲

  • 添加动态配置 Custom Intent Definition
  • 可配置小组件框架代码解析
  • 修改 .intentdefinition 文件实现修改时间类型
  • 代码读取配置信息,实现动态布局

添加动态配置

方式1:新建组件的时候勾选 “Include Configuration Intent” 复选框。



方式2:在您的Xcode项目中,选择“File”>“New File”,然后选择“SiriKit Intent Definition File”。单击”Next“,并在出现提示时保存文件。Xcode在项目中会生成一个新的.intentdefinition 文件。



可配置小组件框架代码解析

  如果默认用方式1 创建组件,代码如下,如果通过方式2,请参考下面的代码对应修改即可,注释中已经标明与普通小组件代码的不同点。

//
//  WidgetConfigIntent.swift
//  WidgetConfigIntent
// import WidgetKit
import SwiftUI
import Intents struct Provider: IntentTimelineProvider {
    func placeholder(in context: Context) -> SimpleEntry {
        // 不同点3:传递默认参数
        SimpleEntry(date: Date(), configuration: ConfigurationIntent())
    }     // 不同点4:比使用StaticConfiguration时多了一个配置参数
    func getSnapshot(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (SimpleEntry) -> ()) {
        let entry = SimpleEntry(date: Date(), configuration: configuration)
        completion(entry)
    }     // 不同点5:比使用StaticConfiguration时多了一个配置参数
    func getTimeline(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
        var entries: [SimpleEntry] = []         // Generate a timeline consisting of five entries an hour apart, starting from the current date.
        let currentDate = Date()
        for hourOffset in 0 ..< 5 {
            let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
            let entry = SimpleEntry(date: entryDate, configuration: configuration)
            entries.append(entry)
        }         let timeline = Timeline(entries: entries, policy: .atEnd)
        completion(timeline)
    }
} struct SimpleEntry: TimelineEntry {
    let date: Date
    // 不同点2: 多了一个配置参数,小组件编辑界面设置参数会通过这个传递进来
    let configuration: ConfigurationIntent
} struct WidgetConfigIntentEntryView : View {
    var entry: Provider.Entry     var body: some View {
        Text(entry.date, style: .time)
    }
} // 小组件入口
@main
struct WidgetConfigIntent: Widget {
    let kind: String = "WidgetConfigIntent"     var body: some WidgetConfiguration {
        //不同点1: 这里使用 IntentConfiguration, 对比 StaticConfiguration
//这里还多了一个参数 intent: ConfigurationIntent.self
        IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider()) { entry in
            WidgetConfigIntentEntryView(entry: entry)
        }
        .configurationDisplayName("可配置小组件")
        .description("选择不同的时间类型")
    }
}
// 调试预览
struct WidgetConfigIntent_Previews: PreviewProvider {
    static var previews: some View {
        WidgetConfigIntentEntryView(entry: SimpleEntry(date: Date(), configuration: ConfigurationIntent()))
            .previewContext(WidgetPreviewContext(family: .systemSmall))
    }
}

修改 .intentdefinition 文件实现修改时间类型

  1. 修改配置名称为TimeTypeConfiguration

  2. 添加参数类型TimeTypeEnum,这里先用枚举类型

  1. 添加参数timeType参数,类型指定为TimeTypeEnum

代码读取配置信息,实现动态布局

  现在编译应该不通过,需要修改一下WidgetConfigIntent.swift中的代码

  1. 把代码中 ConfigurationIntent 替换为 TimeTypeConfigurationIntent(希望到这里你能领悟到点什么)

    运行代码,在桌面添加组件,长按组件 > 编辑小组件可以看到如下图所示(目前点了还没有什么效果)



    代码中获取配置信息,动态改变布局。接下来再编辑小组件,切换时间time/date时界面会发生响应的变化
struct WidgetConfigIntentEntryView : View {
    var entry: Provider.Entry     var body: some View {
        // 根据配置信息动态改变布局
        if (entry.configuration.timeType == TimeTypeEnum.time) {
            Text(entry.date, style: .time)
        } else {
            Text(entry.date, style: .date)
        }
    }
}

结语

  本文讲解了实现一个简单的可配置小组件,不过数据都是静态配置,下一节讲解动态修改配置数据,这个在实际开发中也是比较重要的环节。

IOS Widget(4-1):创建可配置小组件(静态配置数据)的更多相关文章

  1. Yii2 配置request组件解析 json数据

    在基础版本的config目录下 web.php 或者高级版config目录下的main.php中配置 'components' =>[ 'request' => [ 'parsers' = ...

  2. CentOS VMware 配置IP小结 静态 配置 桥接 NAT

    系统启动后可先ping下外网或局域网内其它机器. 如果配置虚拟机时选择的NAT上网方式,后面需要配置固定IP,请先参见VMware NAT方式下设置静态IP获得可用的IP范围和网关等信息. 先将ifc ...

  3. IOS Widget(5):小组件刷新机制

    引言   前面的章节学完已经让我们可以顺利实现一个小组件了,但是小组件里面的数据如何刷新的呢,本节内容将讲解IOS的刷新机制. 大纲 系统如何管理小组件刷新 Timeline刷新机制 Timeline ...

  4. react-router 组件式配置与对象式配置小区别

    1. react-router 对象式配置 和 组件式配置    组件式配置(Redirect) ----对应---- 对象式配置(onEnter钩子) IndexRedirect -----对应-- ...

  5. IOS小组件(8):App与Widget数据共享

    引言   Widget是一个迷你版的App,IOS有沙盒机制,不同App之间无法直接共享数据.组件和主App之间其实就是不同App的关系,所以也无法通过userdefaults.standard来传数 ...

  6. IOS Widget(3):SwiftUI开发小组件布局入门

    引言   经过上一篇文章,我们已经可以在桌面上展示出一个小组件出来了,你肯定想小试牛刀,动手改一改,那我们就从改小组件的布局做起吧.本文不会讲解Swift语法,如果是熟悉Flutter,Kotlin这 ...

  7. Android Widget小组件开发(一)——Android实现时钟Widget组件的步骤开发,这些知识也是必不可少的!

    Android Widget小组件开发(一)--Android实现时钟Widget组件的步骤开发,这些知识也是必不可少的! PS:学习自某网站(不打广告) 这个小组件相信大家都很熟悉吧,以前的墨迹天气 ...

  8. Android开发工程师文集-1 小时学会Widget小组件开发

    前言 大家好,给大家带来Android开发工程师文集-1 小时学会Widget小组件开发的概述,希望你们喜欢 学会用Widget (小组件) Widget小组件很方便,很快捷,可以个性化,自己定制,相 ...

  9. IOS Widget(1):概述

    引言   本系列文章作者是安卓开发,以安卓开发的视角学习IOS小组件,记录一下踩坑记录,如有讲得不对的地方,路过大佬多包涵.如果你是想深入学习小组件,建议您顺着笔者的编号顺序阅读本系列文章.如果曾经了 ...

随机推荐

  1. FreeBSD NGINX TCP转发

    前几天搞转发,研究了下TCP转发,现在记录下来 首先加载模块 注意:这是FreeBSD的位置.并且需要NGINX支持 load_module /usr/local/libexec/nginx/ngx_ ...

  2. EmEditor, 在正则使用()匹配后 使用$1 $2进行对括号内的值进行引用

    $1表示第一个括号,$2表示第二个括号,以此类推

  3. Codeforces Round #557 B. Double Matrix

    题面: 传送门 题目描述: 给出两个n*m的矩阵,问:是否能通过交换两个矩阵"对应"位置的元素,使两个矩阵都为"递增"矩阵. "递增"矩阵定 ...

  4. JSP实验报告

  5. Git - 使用命令和P4Merge进行diff

    P4Merge P4Merge是Git的一个第三发Diff和Merge工具(可视化冲突解决工具). 下载地址: https://www.perforce.com/downloads/visual-me ...

  6. java例题_22 用递归求阶乘 5!

    1 /*22 [程序 22 递归求阶乘] 2 题目:利用递归方法求 5!. 3 程序分析:递归公式:fn!=fn*4! 4 */ 5 6 /*分析 7 * 递归:如果其中每一步都要用到前一步或前几步的 ...

  7. Web 前端 - 浅谈外部手动控制 Promise 状态

    前言 当有多个共享资源.协同操作的时候,往往需要根据动态亦或是复杂的条件以控制和调用程序逻辑. 还是那句话,懂的人自然懂,不懂的人也搜不到这个随笔. 设计 PendingPromise<T> ...

  8. Nacos 2.0 正式发布,性能提升了 10 倍!!

    前不久,在3月20号,Nacos 2.0.0 正式发布了!我简单看了下官方的介绍,可能nacos未来逐渐会成为各大公司作为服务治理和配置中心的主要中间件. Nacos 简介:一个更易于构建云原生应用的 ...

  9. 面试题:让你捉摸不透的 Go reslice

    面试题: package main func a() []int { a1 := []int{3} a2 := a1[1:] return a2 } func main() { a() } 看到这个题 ...

  10. Mybatis3源码笔记(六)SqlSession执行过程

    前几篇大致分析了初始化的过程,今天打算走一个SqlSession具体执行过程. @Test void shouldSelectAllAuthors() { try (SqlSession sessio ...