新聞中心
概覽
小組件一目了然地顯示相關內容,讓用戶可以快速訪問你的 App 以獲取更多詳情。你的 App 可以提供各種各樣的小組件,讓用戶能夠關注對他們來說最重要的信息。他們可以添加同一小組件的多個副本,并能根據他們獨特的需求和布局調整每個副本。如果你在小組件中包含自定意圖,用戶還可以分別對每個小組件進行個性化設定。小組件支持多種尺寸;選擇最適合你的 App 內容的尺寸。由于空間有限,請確保你的小組件呈現用戶最看重的信息。

只需少量設置,以及幾項有關你用戶界面的配置和風格的決策,即可向你的 App 中添加小組件。小組件使用 SwiftUI 視圖顯示其內容。有關更多信息,請參閱“SwiftUI”。
向你的 App 中添加小組件目標
“Widget Extension”(小組件擴展) 模板為你創(chuàng)建小組件提供了一個起點。單個小組件擴展可以包含多個小組件。例如,某個體育 App 可能有一個用于顯示團隊信息的小組件,還有一個用于顯示賽事安排的小組件。單個小組件擴展可以包含這兩個小組件。
在 Xcode 中打開你的 App 項目,并選取“File”(文件) >“New”(新建) >“Target”(目標)。
從“Application Extension”(App 擴展) 組中,選擇“Widget Extension”(小組件擴展),然后點按“Next”(下一步)。
輸入你的擴展的名稱。
如果小組件提供用戶可配置的屬性,請選中“Include Configuration Intent”(包含配置意圖) 復選框。
點按“Finish”(完成)。
盡管你的 App 可以包含多個擴展,但你通常會將所有小組件都包含在單個小組件擴展中。例如,如果你的一些小組件使用位置信息,而另外一些小組件不使用,應將使用位置信息的小組件放在一個單獨的擴展中。這樣可讓系統(tǒng)僅對使用位置信息的擴展中的小組件提示用戶提供使用位置信息的授權。
添加配置詳情
小組件擴展模板提供了一個遵從 Widget 協議的初始小組件實現。這個小組件的 body 屬性用于確定小組件是否有用戶可配置的屬性。提供以下兩種類型的配置:
StaticConfiguration:適用于不含用戶可配置屬性的小組件。例如,用于顯示一般市場信息的股市小組件,或用于顯示熱門新聞標題的新聞小組件。IntentConfiguration:適用于含有用戶可配置屬性的小組件。使用 SiriKit 自定意圖定義屬性。例如,需要城市郵政編碼的天氣小組件,或需要物流跟蹤編號的包裹物流跟蹤小組件。
“Include Configuration Intent”(包含配置意圖) 復選框用于確定 Xcode 使用哪個配置。當你選中這個復選框時,Xcode 會使用意圖配置,否則將使用靜態(tài)配置。為初始化配置,請?zhí)峁┮韵滦畔ⅲ?/p>
種類:一個用于標識小組件的字符串。這是你選擇的一個標識符,應描述小組件所呈現的內容。
提供程序:一個符合
TimelineProvider的對象,它將生成時間線來告訴 WidgetKit 何時呈現小組件。時間線包含你定義的自定TimelineEntry類型。時間線條目用于標識你希望 WidgetKit 更新小組件內容的日期。包含你的小組件視圖需要在自定類型中呈現的屬性。內容閉包:包含 SwiftUI 視圖的閉包。WidgetKit 調用它來呈現小組件的內容,從提供程序傳遞一個
TimelineEntry參數。自定意圖:自定意圖用于定義用戶可配置的屬性。有關添加自定的更多信息,請參閱“制作可配置小組件”。
使用修飾符提供其他配置詳情,包括顯示名稱、描述和小組件支持的系列。以下代碼顯示了一個小組件,該小組件用于提供游戲的通用、不可配置的狀態(tài):
@main struct GameStatusWidget: Widget { var body: some WidgetConfiguration { StaticConfiguration( kind: "com.mygame.game-status", provider: GameStatusProvider(), ) { entry in GameStatusView(entry.gameStatus) } .configurationDisplayName("Game Status") .description("Shows an overview of your game status") .supportedFamilies([.systemSmall, .systemMedium, .systemLarge]) } }
小組件的提供程序為小組件生成時間線,并在每個條目中包含游戲狀態(tài)詳情。當每個時間線條目的日期都到達后,WidgetKit 調用 content 閉包來顯示小組件的內容。最后,修飾符指定在小組件庫中顯示的名稱和描述,并允許用戶選擇小組件的小尺寸、中尺寸或大尺寸版本。
重要信息
為使 App 的小組件出現在小組件庫中,用戶必須在安裝包含小組件的 App 后至少啟動該 App 一次。
注意 @main 屬性在這個小組件中的用法。這個屬性指示 GameStatusWidget 是小組件擴展的入口點,暗示該擴展包含單個小組件。要支持多個小組件,請參閱“在你的 App 擴展中聲明多個小組件”。
提供時間線條目
時間線提供程序生成一個由時間線條目構成的時間線,每個條目都指定更新小組件內容的日期和時間。游戲狀態(tài)小組件在定義其時間線條目時可能會包含一個表示游戲狀態(tài)的字符串,如下所示:
struct GameStatusEntry: TimelineEntry { var date: Date var gameStatus: String }
要在小組件庫中顯示你的小組件,WidgetKit 會要求提供程序提供預覽快照。可以通過檢查傳遞給 getSnapshot(in:completion:) 方法的 context 參數的 isPreview 屬性來識別這一預覽請求。當 isPreview 為 true 時,WidgetKit 會在小組件庫中顯示你的小組件。作為回應,你需要快速創(chuàng)建預覽快照。如果小組件所需的資產或信息需要一些時間才能生成或從服務器獲取,請改用示例數據。
在以下代碼中,為實現快照方法,游戲狀態(tài)小組件的提供程序會在尚未完成從服務器獲取狀態(tài)的操作時顯示一個空狀態(tài):
struct GameStatusProvider: TimelineProvider { var hasFetchedGameStatus: Bool var gameStatusFromServer: String func getSnapshot(in context: Context, completion: @escaping (Entry) -> Void) { let date = Date() let entry: GameStatusEntry if context.isPreview && !hasFetchedGameStatus { entry = GameStatusEntry(date: date, gameStatus: "—") } else { entry = GameStatusEntry(date: date, gameStatus: gameStatusFromServer) } completion(entry) }
在請求初始快照后,WidgetKit 調用 getTimeline(in:completion:) 以向提供程序請求定期時間線。時間線由一個或多個時間線條目以及一個重新載入策略構成,該策略用于告知 WidgetKit 何時請求后續(xù)時間線。
以下示例顯示了游戲狀態(tài)小組件的提供程序如何生成一個時間線,使其包含帶有來自服務器的當前游戲狀態(tài)的單個條目以及在 15 分鐘后請求新時間線的重新載入策略:
struct GameStatusProvider: TimelineProvider { func getTimeline(in context: Context, completion: @escaping (Timeline) -> Void) { // Create a timeline entry for "now." let date = Date() let entry = GameStatusEntry( date: date, gameStatus: gameStatusFromServer ) // Create a date that's 15 minutes in the future. let nextUpdateDate = Calendar.current.date(byAdding: .minute, value: 15, to: date)! // Create the timeline with the entry and a reload policy with the date // for the next update. let timeline = Timeline( entries:[entry], policy: .after(nextUpdateDate) ) // Call the completion to pass the timeline to WidgetKit. completion(timeline) } }
在這個示例中,如果小組件沒有來自服務器的當前狀態(tài),它可以存儲對 completion 的引用,向服務器發(fā)起異步請求以獲取游戲狀態(tài),并在該請求完成時調用 completion。
有關生成時間線的更多信息,包括處理小組件中的網絡請求,請參閱“讓小組件保持最新狀態(tài)”。
顯示占位符小組件
當 WidgetKit 首次顯示你的小組件時,它會將小組件的視圖呈現為一個占位符。占位符視圖顯示小組件的通用表示,讓用戶可以大致了解小組件顯示的內容。WidgetKit 調用 placeholder(in:) 來請求表示小組件占位符配置的條目。例如,游戲狀態(tài)小組件將按如下所示實現這一方法:
struct GameStatusProvider: TimelineProvider { func placeholder(in context: Context) -> SimpleEntry { GameStatusEntry(date: Date(), gameStatus: "—") } }
為了將小組件的視圖呈現為占位符,WidgetKit 使用 redacted(reason:) 視圖修飾符并指定 placeholder 作為 reason。為防止小組件視圖層次結構中的視圖自動呈現為占位符,請使用 unredacted() 視圖修飾符。
如果你在小組件擴展中啟用“Data Protection”(數據保護) 功能,則當數據保護授權指定以下值且關聯的條件得到滿足時,WidgetKit 會將你的小組件呈現為占位符:
NSFileProtectionComplete或NSFileProtectionCompleteUnlessOpen,且設備已鎖定。NSFileProtectionCompleteUntilFirstUserAuthentication,且用戶還沒有進行身份驗證。
有關配置數據保護的更多信息,請參閱“數據保護授權”。
在你的小組件中顯示內容
小組件使用一個 SwiftUI 視圖定義其內容,通常通過組合其他 SwiftUI 視圖實現。如“添加配置詳情”部分中所示,小組件的配置包含 WidgetKit 為呈現小組件內容而調用的閉包。
當用戶從小組件庫中添加你的小組件時,他們會從小組件支持的系列中選擇特定的系列 (小尺寸、中尺寸或大尺寸)。小組件的內容閉包必須能夠呈現小組件支持的每個系列。WidgetKit 在 SwiftUI 環(huán)境中設置相應的系列和其他屬性,例如配色方案 (淺色或深色)。
在上面顯示的游戲狀態(tài)小組件配置中,內容閉包使用 GameStatusView 來顯示狀態(tài)。小組件支持全部三個小組件系列,而它會使用 widgetFamily 來決定顯示哪個特定的 SwiftUI 視圖,如下所示:
struct GameStatusView : View { @Environment(\.widgetFamily) var family: WidgetFamily var gameStatus: GameStatus @ViewBuilder var body: some View { switch family { case .systemSmall: GameTurnSummary(gameStatus) case .systemMedium: GameStatusWithLastTurnResult(gameStatus) case .systemLarge: GameStatusWithStatistics(gameStatus) default: GameDetailsNotAvailable() } } }
對于小尺寸系列,小組件所用的視圖顯示游戲中當前輪到的玩家的簡單摘要。對于中尺寸系列,它顯示狀態(tài)以指示上一輪的結果。對于大尺寸系列,由于有更多可用空間,它顯示每個玩家的運行統(tǒng)計數據。如果系列是未知類型,則顯示默認視圖,表示游戲狀態(tài)不可用。
注釋
由于視圖使用的視圖類型有所差異,因此它使用 @ViewBuilder 聲明其主體。
對于可配置的小組件,提供程序符合 IntentTimelineProvider。這個提供程序與 TimelineProvider 執(zhí)行相同的功能,但它包含用戶在小組件上自定的值。意圖時間線提供程序可以在傳遞給 getSnapshot(for:in:completion:) 和 getTimeline(for:in:completion:) 的 configuration 參數中使用這些自定項。你通常會將用戶配置的值作為自定時間線條目類型的屬性包含在內,以便詳情可在小組件的視圖中顯示。
重要信息
小組件顯示只讀信息,不支持交互式元素,如滾動元素或開關。WidgetKit 在呈現小組件的內容時會忽略交互式元素。
有關 WidgetKit 支持的視圖列表,請參閱“SwiftUI 視圖”。
向你的小組件中添加動態(tài)內容
盡管小組件的顯示基于視圖的快照,但你可以使用各種可在小組件顯示時繼續(xù)更新的 SwiftUI 視圖。有關提供動態(tài)內容的更多信息,請參閱“讓小組件保持最新狀態(tài)”。
響應用戶互動
當用戶與你的小組件進行互動時,系統(tǒng)將啟動你的 App 來處理請求。當系統(tǒng)激活你的 App 時,導航到與小組件內容對應的詳細信息。你的小組件可以指定一個 URL 來告知 App 要顯示的內容。要在你的小組件中配置自定 URL:
對于所有小組件,將
widgetURL(_:)視圖修飾符添加到小組件視圖層次結構中的視圖。如果小組件的視圖層次結構包含多個widgetURL修飾符,則無法定義行為。對于使用
WidgetFamily.systemMedium或WidgetFamily.systemLarge的小組件,向小組件的視圖層次結構中添加一個或多個Link控件。你可以同時使用widgetURL和Link控件。如果互動的目標為某個Link控件,則系統(tǒng)將使用該控件中的 URL。對于小組件中任何其他位置的互動,系統(tǒng)將使用在widgetURL視圖修飾符中指定的 URL。
例如,用于顯示游戲中單個角色的詳情的小組件可以使用 widgetURL 打開 App 以顯示該角色的詳情。
@ViewBuilder var body: some View { ZStack { AvatarView(entry.character) .widgetURL(entry.character.url) .foregroundColor(.white) } .background(Color.gameBackground) }
如果小組件顯示角色列表,則列表中的每一項都可以在 Link 控件中。每個 Link 控件都會指定它所顯示的特定角色的 URL。
當小組件收到互動時,系統(tǒng)會激活包含 App 并將 URL 傳遞給 onOpenURL(perform:)、application(_:open:options:) 或 application(_:open:),具體取決于你的 App 使用的生命周期。
如果小組件沒有使用 widgetURL 或 Link 控件,系統(tǒng)將激活包含 App 并將 NSUserActivity 傳遞給 onContinueUserActivity(_:perform:)、application(_:continue:restorationHandler:) 或 application(_:continue:restorationHandler:)。用戶活動的 userInfo 字典包含與用戶互動的小組件的詳細信息。使用 WidgetCenter.UserInfoKey 中的密鑰訪問 Swift 代碼中的這些值。要訪問 Objective-C 中的 userInfo 值,請改用 WGWidgetUserInfoKeyKind 和 WGWidgetUserInfoKeyFamily 密鑰。
對于使用 IntentConfiguration 的小組件,用戶活動的 interaction 屬性包含小組件的 INIntent。
在你的 App 擴展中聲明多個小組件
上面的 GameStatusWidget 示例使用 @main 屬性指定小組件擴展的單個入口點。為支持多個小組件,需要聲明一個符合 WidgetBundle 的結構,該結構會在其 body 屬性中將多個小組件組合在一起。在這個 widget-bundle 結構上添加 @main 屬性,以告訴 WidgetKit 你的擴展支持多個小組件。
例如,如果游戲 App 有第二個小組件用于顯示角色生命值,第三個小組件用于顯示排行榜,則它會將這些小組件組合在一起,如下所示:
@main struct GameWidgets: WidgetBundle { @WidgetBundleBuilder var body: some Widget { GameStatusWidget() CharacterDetailWidget() LeaderboardWidget() } }
當前名稱:創(chuàng)新互聯IOS教程:創(chuàng)建小組件擴展
當前URL:http://www.5511xx.com/article/dhsisid.html


咨詢
建站咨詢
