stackoverflow参考
https://stackoverflow.com/questions/78716058/ios-18-control-widget-that-opens-a-url
custom image 必须用SFSymbol
根据苹果文档,ControlWidget符合ControlWidgetTemplate,该模板表示
这些模板定义了图像(具体而言,符号图像)
因此,为了拥有自定义图像,该图像必须是SF符号。您可以参考本文档进行自定义实现。或者您只需使用App Store中的“创建自定义符号”应用程序。只需在应用程序中打开您现有的SVG,它就会创建一个自定义的SFSymbol。
具体代码
import SwiftUI
import WidgetKit
import AppIntents
import UIKit
// 使用 ControlWidget 协议来定义一个基础控件,定义了一个新的结构体 WidgetToggle,它实现了 ControlWidget 协议。
struct WidgetButton: ControlWidget {
// body属性表示该 WidgetButton 中包含的控件列表。
var body: some ControlWidgetConfiguration {
// // 这是一个静态配置,用于定义控件的结构:外观和行为。
StaticControlConfiguration(
kind: "com.apple.ControlWidgetButton"
) {
// 定义了一个打开容器App的控件,
ControlWidgetButton(action: OpenAppIntent()) {
Label("WidgetButton", image: "PPTEST.symbols")
} actionLabel: { isActive in
Label("WidgetButton", image: "PPTEST.symbols")
}
}
.displayName("pzx")
.description("Pzx")
}
}
struct OpenPhotoCalorieControlWidget:ControlWidget {
let kind = "OpenPhotoCalorieControlWidget"
var body: some ControlWidgetConfiguration {
StaticControlConfiguration(kind: kind) {
ControlWidgetButton(action: OpenAppIntent()) {
Image(systemName: "camera.viewfinder")
}
}
.displayName(LocalizedStringResource("拍照记饮食"))
.promptsForUserConfiguration()
}
}
struct OpenAppIntent: AppIntent {
static var title: LocalizedStringResource { "Open App" }
static var openAppWhenRun:Bool = true
func perform() async throws -> some IntentResult {
NotificationCenter.default.post(name: Notification.Name("OpenAppNotification"), object: nil, userInfo: ["parameter": "specialParameter"])
return .result()
}
}
ControlWidget 是样式部分,AppIntent是实现部分打开App通过NotificationCenter传递事件给主工程
如果是用的SceneDelegate
在sceneWillEnterForeground
通过通知接受即可
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
NotificationCenter.default.removeObserver(self, name: Notification.Name("OpenAppNotification"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleOpenAppNotification(_:)), name: Notification.Name("OpenAppNotification"), object: nil)
}
@objc private func handleOpenAppNotification(_ notification: Notification) {
if let userInfo = notification.userInfo, let specialParameter = userInfo["parameter"] as? String {
// 根据 specialParameter 处理页面跳转逻辑
print("specialParameter = \(specialParameter)")
DispatchQueue.main.async {
let currentVC = PZXKeyController()
let newVC = SecondViewController() // 创建要推送的视图控制器
if let navController = currentVC.navigationController {
navController.pushViewController(newVC, animated: true)
}
}
}
}
如果是AppDelegate
类似,在即将进入前台是使用。