iOS中点击主按钮后如何更新ShieldConfiguration的UI?
解决ManagedSettings点击按钮后更新屏蔽界面UI的问题
ManagedSettings框架下,屏蔽界面的UI配置由ShieldConfigurationDataSource提供,但系统会主动拉取配置而非允许直接修改已展示的界面。你不需要注入类,正确的做法是通过ManagedSettingsStore传递状态,触发系统重新加载配置。
步骤1:在按钮点击时更新存储状态
在ShieldActionExtension的按钮处理逻辑中,使用ManagedSettingsStore存储点击状态,这样后续配置拉取时能读取到状态变化:
class ShieldActionExtension: ShieldActionDelegate { override func handle(action: ShieldAction, for application: ApplicationToken, completionHandler: @escaping (ShieldActionResponse) -> Void) { switch action { case .primaryButtonPressed: let store = ManagedSettingsStore() // 给当前应用的屏蔽配置添加自定义状态标记 store.shield.applications[application.bundleIdentifier]?.customValues["hasClickedPrimaryButton"] = true // 返回.defer让系统重新加载屏蔽界面配置 completionHandler(.defer) default: // 处理其他按钮逻辑 completionHandler(.dismiss) } } }
步骤2:根据存储状态动态生成配置
修改ShieldConfigurationExtension的configuration方法,读取ManagedSettingsStore中的状态,返回不同的UI配置:
class ShieldConfigurationExtension: ShieldConfigurationDataSource { override func configuration(shielding application: Application) -> ShieldConfiguration { let store = ManagedSettingsStore() // 读取之前存储的状态,默认未点击 let hasClicked = store.shield.applications[application.bundleIdentifier]?.customValues["hasClickedPrimaryButton"] as? Bool ?? false // 根据状态生成差异化的配置 let config = ShieldConfiguration( backgroundBlurStyle: .systemMaterialLight, backgroundColor: hasClicked ? UIColor(red: 0.66, green: 0.98, blue: 0.71, alpha: 1.0) : UIColor(red: 0.71, green: 0.66, blue: 0.98, alpha: 1.0), icon: UIImage(named: hasClicked ? "check-icon" : "doxoblocker"), title: ShieldConfiguration.Label(text: hasClicked ? "操作已确认" : "Life is short.", color: .black), subtitle: ShieldConfiguration.Label(text: hasClicked ? "感谢你的配合" : "But if you wanna use this app,\nlet’s make sure to pay.", color: .black), primaryButtonLabel: ShieldConfiguration.Label(text: hasClicked ? "完成" : "Thanks!", color: .white), primaryButtonBackgroundColor: .black, secondaryButtonLabel: ShieldConfiguration.Label(text: "Break 👀", color: .black) ) return config } }
关键说明
ManagedSettingsStore是跨进程的状态存储,主App和屏蔽扩展都能访问,是传递状态的标准方式- 返回
.defer会让系统重新调用configuration方法,从而更新界面;如果返回.dismiss则会直接关闭屏蔽界面 - 若需要重置状态,可在适当时机(比如用户完成后续操作后)修改
store中的值,系统会再次更新界面
内容的提问来源于stack exchange,提问作者Tejas Sharma
相关产品推荐
相关产品推荐

