ios小组件开发

一、小组件开发概念介绍

小组件是App Extension的一种,前身为iOS8推出的Today Extension,只能添加到负一屏。

iOS14推出Widget Extension取代Today Extension。 相比Today ExtensionWidget Extension可以添加到桌面,并且支持了更多的尺寸,可以承载更多内容。

小组件开发依赖的主要官方框架是WidgetKit,界面开发需要使用SwiftUI,自定义配置、点击交互等和SiriKit的机制相同。

SwiftUI是苹果2019年推出的构建界面的声明式框架,相对UIKit具有更高的开发效率和更好的可读性等优点。

二、小组件的创建

1.小组件的创建方式

1、在 Xcode 中打开 App 项目,并选取"File > New > Target" ,选择 "Widget Extension"

2.点击next

如果都不勾选系统默认创建入口文件(myExtensionWidgetBundle.swift)和一个widget(myExtensionWidget.swift)

 可以自己创建多个小组件添加到myExtensionWidgetBundle.swift中创建多个小组件。

 有三个可选项:

  • Include Live Activity(灵动岛、实时活动相关
  • Include Control
  • Include Configuration App Intent

2.小组件的入口文件:

使用 @main 属性指定小组件扩展的单个入口点。为支持多个小组件,需要声明一个符合 WidgetBundle 的结构,该结构会在其 body 属性中将多个小组件组合在一起。在这个 widget-bundle 结构上添加 @main 属性,以告诉 WidgetKit 你的扩展支持多个小组件。

import WidgetKit
import SwiftUI

@main
struct MyWidgetBundle: WidgetBundle {
    var body: some Widget {
        MyWidget()
        MyWidgetControl()
        MyWidgetLiveActivity()
    }
}

注意:@WidgetBundleBuilderbuildBlock方法最多支持传入10个遵守Widget协议的参数,因此一个WidgetBundle最多可以支持放10个Widget。但可以 通过嵌套方式实现多个

@main
struct MyWidgetBundle: WidgetBundle {
    var body: some Widget {
        MyChildWidgetBundle().body
        // 最多可以放10个`MyChildWidgetBundle().body`
    }
}

struct MyChildWidgetBundle: WidgetBundle {
    var body: some Widget {
        MyGrandsonWidgetBundle().body
        // 最多可以放10个`MyGrandsonWidgetBundle().body`
    }
}

struct MyGrandsonWidgetBundle: WidgetBundle {
    var body: some Widget {
        MyWidget() 
        // 最多可以放10个`MyWidget()`
    }
}

3.小组件的尺寸

目前小组件支持设置基础的三个尺寸,即:小、中、大。 

struct MyWidget: Widget {
    let kind: String = "MyWidget" // 唯一标识

    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind, provider: Provider()) { entry in
            MyWidgetEntryView(entry: entry)
        }
        .configurationDisplayName("这是小组件的名称")
        .description("这是小组件的描述.")
        .supportedFamilies([.systemSmall, .systemMedium, .systemLarge,.systemExtraLarge]) // 支持小、中、大尺寸,超大
    }
}

 注意:systemExtraLarge是ios15之后才会支持。

从 iOS 16 开始,支持 accessoryCircular 、 accessoryRectangular 和 accessoryInline 类型,这几种小部件可以用在手表中,也可以出现在 iOS 的锁定屏幕上。

在 Widget View 中可以从环境变量(Environment)中获取当前的小组件类型,获取之后以做不同的 UI 适配:

// 环境变量获取当前的小组件类型
    @Environment(\.widgetFamily) var family: WidgetFamily

Include Live Activity

如果勾选Include Live Activity,系统会默认给我们创建一个myExtensionWidgetLiveActivity.swift文件

import ActivityKit
import WidgetKit
import SwiftUI

struct myExtensionWidgetAttributes: ActivityAttributes {
    public struct ContentState: Codable, Hashable {
        // Dynamic stateful properties about your activity go here!
        var emoji: String
    }

    // Fixed non-changing properties about your activity go here!
    var name: String
}

struct myExtensionWidgetLiveActivity: Widget {
    var body: some WidgetConfiguration {
        ActivityConfiguration(for: myExtensionWidget2Attributes.self) { context in
            // Lock screen/banner UI goes here
            VStack {
                Text("Hello \(context.state.emoji)")
            }
            .activityBackgroundTint(Color.cyan)
            .activitySystemActionForegroundColor(Color.black)

        } dynamicIsland: { context in
            DynamicIsland {
                // Expanded UI goes here.  Compose the expanded UI through
                // various regions, like leading/trailing/center/bottom
                DynamicIslandExpandedRegion(.leading) {
                    Text("Leading")
                }
                DynamicIslandExpandedRegion(.trailing) {
                    Text("Trailing")
                }
                DynamicIslandExpandedRegion(.bottom) {
                    Text("Bottom \(context.state.emoji)")
                    // more content
                }
            } compactLeading: {
                Text("L")
            } compactTrailing: {
                Text("T \(context.state.emoji)")
            } minimal: {
                Text(context.state.emoji)
            }
            .widgetURL(URL(string: "http://www.apple.com"))
            .keylineTint(Color.red)
        }
    }
}

extension myExtensionWidgetAttributes {
    fileprivate static var preview: myE
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值