日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

IOS小组件(4-2):创建可配置小组件(动态修改配置数据)

發布時間:2024/1/4 综合教程 31 生活家
生活随笔 收集整理的這篇文章主要介紹了 IOS小组件(4-2):创建可配置小组件(动态修改配置数据) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

引言

??上一篇文章,講解了如果通過配置修改小組件行為,只不過配置數據是寫死的,本文將繼續探索配置數據的高級用法,配置數據在小組件中動態創建的

大綱

在項目中添加”Intents Extension“
在 xxx.intentdefinition文件中增加一個動態類型
實現 Intent Handler 提供動態配置數據

在項目中添加”Intens Extension“

??要實現動態修改配置數據,需要向應用程序添加一個"Intens Extension"。當用戶編輯窗口小部件時,WidgetKit會加載"Intens Extension"以提供動態信息。要添加"Intens Extension",請執行以下操作:

選擇“File”>“New”>“Target”,然后選擇"Intens Extension"。

點擊"Next"。
輸入Intent Extension的名稱(這里我們設置為DynamicTimer),并將"Starting Point"設置為None。

單擊完成。如果Xcode提示您有關激活"new scheme"信息,請單擊“Activate”。
在新Target的屬性的“Gneral”選項卡中,在“Supported Intents”部分中添加一個條目,并將“Class Name”設置為 "TimeTypeConfigurationIntent". Xcode會自動把xxx.intentdefinition中的配置轉為代碼,放到這個文件中。

如果不設置這項,也會自動生成,這個名字怎么來的呢?就是CUSTOM INTENTS中的名字后面加個Intent

在項目導航器中,選擇之前添加的自定義 intent definition 文件。
右鍵選擇”Show File Inspector“,將”“intent definition”文件添加到前新建的Target中。

在 xxx.intentdefinition文件中增加一個動態類型

??上一篇文章中,我們使用的靜態類型(枚舉)來實現修改Timer類型。要支持動態修改,則需要使用動態類型。創建步驟如下

從“類型”彈出菜單中,選擇“New Type”。Xcode在編輯器的“TYPES”中添加了一個新類型。
將類型的名稱更改為 "DynamicTimeType"

添加一個新屬性“dynamicTime”,然后Type選擇“String”。

在CUSTOM INTENTS中選擇 TimeTypeConfiguration
新增一個動態參數 dynamicTimeType
在 Intent 編輯器中,選中“Dynamic Options”復選框,表示代碼將為此參數提供了動態的選項列表。

實現 Intent Handler 提供動態配置數據

??經過上面的步驟,我們準備好了所有的配置信息,這時候我們編譯一下項目,Xcode會根據xxx.intentdefinition文件生成對應的代碼。接下來我們要修改DynamicTimer這個Target中的IntentHandler.swift中的代碼。修改過的代碼如下:

//
// IntentHandler.swift
// DynamicTimer
//

import Intents

// TimeTypeConfigurationIntentHandling 這個類在
// TimeTypeConfigurationIntent.swift文件中,這個文件是Xcode生成的。
// 這個文件名怎么來的? =>
// Target的屬性的“Gneral”選項卡中,在“Supported Intents”部分中添加一個條目,
// 并將“Class Name”設置為 "TimeTypeConfigurationIntent".
// Xcode會自動把xxx.intentdefinition中的配置轉為代碼,放到這個文件中。
class IntentHandler: INExtension, TimeTypeConfigurationIntentHandling {
  func provideDynamicTimeTypeOptionsCollection(
    for intent: TimeTypeConfigurationIntent,
    with completion: @escaping (INObjectCollection<DynamicTimeType>?, Error?) -> Void) {
   
    let time = DynamicTimeType(identifier: "time", display: "時間")
    time.dynamicTime = "time"
    let date = DynamicTimeType(identifier: "date", display: "時期")
    date.dynamicTime = "date"
    let timer = DynamicTimeType(identifier: "timer", display: "計時器")
    timer.dynamicTime = "timer"
    let allTimeType = [
      time, date, timer
    ]
    // 生成一個數組,把數據通過回調方法傳出去
    completion(INObjectCollection(items: allTimeType), nil)
  }
 
  override func handler(for intent: INIntent) -> Any {
    // This is the default implementation. If you want different objects to handle different intents,
    // you can override this and return the handler you want for that particular intent.
    return self
  } 
}

運行效果,從桌面點擊組件,右鍵編輯小組件

目前選擇之后還沒生效,因為我們布局里面還沒有使用這個值,接下來就修改代碼,獲取這個值,根據這個值動態改變時間類型。

//
// WidgetConfigIntent.swift
// WidgetConfigIntent
//

import WidgetKit
import SwiftUI
import Intents

struct Provider: IntentTimelineProvider {
  func placeholder(in context: Context) -> SimpleEntry {
    // 不同點3:傳遞默認參數
    SimpleEntry(date: Date(), configuration: TimeTypeConfigurationIntent())
  }

  // 不同點4:比使用StaticConfiguration時多了一個配置參數
  func getSnapshot(for configuration: TimeTypeConfigurationIntent, in context: Context, completion: @escaping (SimpleEntry) -> ()) {
    let entry = SimpleEntry(date: Date(), configuration: configuration)
    completion(entry)
  }

  // 不同點5:比使用StaticConfiguration時多了一個配置參數
  func getTimeline(for configuration: TimeTypeConfigurationIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
    var entries: [SimpleEntry] = []

    // Generate a timeline consisting of five entries an hour apart, starting from the current date.
    let currentDate = Date()
    for hourOffset in 0 ..< 5 {
      let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
      let entry = SimpleEntry(date: entryDate, configuration: configuration)
      entries.append(entry)
    }

    let timeline = Timeline(entries: entries, policy: .atEnd)
    completion(timeline)
  }
}

struct SimpleEntry: TimelineEntry {
  let date: Date
  // 不同點2: 多了一個配置參數,小組件編輯界面設置參數會通過這個傳遞進來
  let configuration: TimeTypeConfigurationIntent
}

struct WidgetConfigIntentEntryView : View {
  var entry: Provider.Entry

  var body: some View {
    // 根據靜態配置信息動態改變布局
//    if (entry.configuration.timeType == TimeTypeEnum.time) {
//      Text(entry.date, style: .time)
//    } else {
//      Text(entry.date, style: .date)
//    }
    // 根據動態配置信息動態改變布局
    if (entry.configuration.dynamicTimeType?.dynamicTime == "time") {
      Text(entry.date, style: .time)
    } else if (entry.configuration.dynamicTimeType?.dynamicTime == "timer") {
      Text(entry.date, style: .timer)
        .multilineTextAlignment(.center)
    } else {
      Text(entry.date, style: .date)
    }
  }
}

// 小組件入口
@main
struct WidgetConfigIntent: Widget {
  let kind: String = "WidgetConfigIntent"

  var body: some WidgetConfiguration {
    //不同點1: 這里使用 IntentConfiguration, 對比 StaticConfiguration,這里還多了一個參數 intent: ConfigurationIntent.self
    IntentConfiguration(kind: kind, intent: TimeTypeConfigurationIntent.self, provider: Provider()) { entry in
      WidgetConfigIntentEntryView(entry: entry)
    }
    .configurationDisplayName("可配置小組件")
    .description("選擇不同的時間類型")
  }
}

// Debug調試代碼
struct WidgetConfigIntent_Previews: PreviewProvider {
  static var previews: some View {
    WidgetConfigIntentEntryView(entry: SimpleEntry(date: Date(), configuration: TimeTypeConfigurationIntent()))
      .previewContext(WidgetPreviewContext(family: .systemSmall))
  }
}

運行效果
選擇計時器

選擇時間

選擇日期

結語

??本文內容講解了如何動態修改配置數據,重點就是配置xxx.intentdefinition文件,一定要自己親自操作一次,不然不容易理解配置是怎么跟代碼對應起來的。

總結

以上是生活随笔為你收集整理的IOS小组件(4-2):创建可配置小组件(动态修改配置数据)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。