iOS 小组件开发第三篇:实战

这里每天分享一个 iOS 的新知识,快来关注我吧

前言

iOS 小组件开发第一篇:基础介绍

iOS 小组件开发第二篇:时间线

前两天讲了小组件的基础内容,今天准备带大家写一个非常简单的小组件项目。

先说下需求,实现一个可以展示上午、下午、夜里三种状态的小组件,分别用三个不同的图标来显示。

按照上述需求,我们简单地把这个小组件的时间线描述出来,有 3 个阶段:

  1. 早上 8 点到中午 12 点为上午

  2. 中午 12 点到下午 6 点为下午

  3. 下午 6 点到早上 8 点为夜里

TimelineEntry

昨天的文章提到,TimelineEntry 是用来提供小组件显示内容和时间的,那么我们需要先写一个展示时间状态的枚举,用来表示上午、下午和晚上,然后在 SimpleEntry 中声明这个属性:

csharp 复制代码
struct SimpleEntry: TimelineEntry {
    enum Time {
        case morning, afternoon, night
    }
    
    let date: Date
    // 表示上午、下午、晚上
    let time: Time
}

Provider

然后是 Provider 的实现,placeholder 方法中直接返回一个固定的 Entry

less 复制代码
func placeholder(in context: Context) -> SimpleEntry {
    SimpleEntry(date: Date(), time: .morning)
}

然后是 getSnapshot 方法,这里依然返回一个固定的 morning

less 复制代码
func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
    let entry = SimpleEntry(date: Date(), time: .morning)
    completion(entry)
}

然后在运行程序,在组件库中就可以看到这个预览了:

最后是最重要的 getTimeline 方法,我们需要在这里把时间线给到系统,我的思路是,先拿到当前时间,判断是上午、下午还是晚上,如果是上午,则添加上午、下午、和晚上的时间条目。如果当前是下午,则添加下午和晚上的时间条目,如果是晚上,则只添加晚上的时间线条目。

首先写个方法来获取指定小时的时间,这个方法传入小时,返回当天这个小时的时间:

sql 复制代码
func getDate(in hour: Int) -> Date {
    let calendar = Calendar.current
    var components = calendar.dateComponents([.year, .month, .day], from: Date())
    components.hour = hour
    components.minute = 0
    components.second = 0

    return calendar.date(from: components)!
}

然后写具体的时间线条目的代码:

less 复制代码
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
    var entries: [SimpleEntry] = []
    
    let hour = Calendar.current.component(.hour, from: Date())
    
    switch hour {
    case 8..<12:
        entries.append(SimpleEntry(date: Date(), time: .morning))
        entries.append(SimpleEntry(date: getDate(in: 12), time: .afternoon))
        entries.append(SimpleEntry(date: getDate(in: 18), time: .night))

    case 12..<18:
        entries.append(SimpleEntry(date: Date(), time: .afternoon))
        entries.append(SimpleEntry(date: getDate(in: 18), time: .night))

    default:
        entries.append(SimpleEntry(date: Date(), time: .night))
    }
    
    let timeline = Timeline(entries: entries, policy: .atEnd)
    completion(timeline)
}

UI 渲染

为了能够正常显示文案和图标,我给 Time 枚举做了扩展,为不同的 case 返回不同的图标和标题:

swift 复制代码
extension SimpleEntry.Time {
    var text: String {
        switch self {
        case .morning:
            return "上午"
        case .afternoon:
            return "下午"
        case .night:
            return "晚上"
        }
    }
    
    var icon: String {
        switch self {
        case .morning:
            return "sunrise"
        case .afternoon:
            return "sun.max.fill"
        case .night:
            return "sunset"
        }
    }
}

最后是 SwiftUI 渲染代码,我用一个 VStack 包裹外层,里边先是一个图标,然后是个 HStack 来展示文本内容:

scss 复制代码
struct MyWidgetEntryView : View {
    var entry: Provider.Entry
    var body: some View {
        VStack(spacing: 10) {
            Image(systemName: entry.time.icon)
                .imageScale(.large)
                .fontWeight(.medium)
                .foregroundColor(.red)
            HStack {
                Text("现在是:")
                Text(entry.time.text)
            }
            .font(.subheadline)
        }
    }
}

其他部分的代码不需要改动,保持创建工程时的状态即可。

看下效果

这样,我们的小组件就完成了:

明天继续讲小组件!

这里每天分享一个 iOS 的新知识,快来关注我吧

本文同步自微信公众号 "iOS新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
2501_915918412 小时前
中小团队发布,跨平台 iOS 上架,证书、描述文件创建管理,测试分发一体化方案
android·ios·小程序·https·uni-app·iphone·webview
家里有只小肥猫2 小时前
uniApp打包ios报错
ios·uni-app
TheNextByte13 小时前
将 iPhone数据备份到闪存盘/USB 驱动器的3 种方法
ios·iphone
TheNextByte14 小时前
如何在 iPhone 上共享联系人? 【6个有效方法】
ios·iphone
Hubianji_094 小时前
[IOS]2026年网络安全、通信技术与计算机科学国际会议(ACCTCS 2026)
计算机网络·安全·web安全·ios·国际会议·国际期刊
pop_xiaoli4 小时前
effective-Objective-C 第一章阅读笔记
开发语言·笔记·ios·objective-c·cocoa·xcode
恋猫de小郭4 小时前
小米 HyperOS 4 大变样?核心应用以 Rust / Flutter 重写,不兼容老系统
android·前端·人工智能·flutter·ios
June bug4 小时前
【领域知识】一个休闲游戏产品(安卓和iOS)从0到1
android·ios
2501_915106325 小时前
iOS 如何绕过 ATS 发送请求,iOS调试
android·ios·小程序·https·uni-app·iphone·webview
鹏北海-RemHusband5 小时前
踩坑记录:iOS Safari 软键盘下的“幽灵弹窗“问题
前端·ios·safari