In diesem Artikel werde ich die Widget-Funktion von iOS14 vorstellen und implementieren.
Umgebung OS:Catlina 10.15.4 Xcode:12.2 beta2
Apple hat eine API bereitgestellt, mit der Sie auf Apps mit einfachen Funktionen wie Kalendern und Timern auf das Benachrichtigungscenter zugreifen können, das angezeigt wird, wenn Sie vom Startbildschirm von "iOS 8" nach links wischen, aber mit "iOS 14" auf dem Startbildschirm Das kann jetzt angezeigt werden. Die Funktionalität wurde weiter verbessert und der angezeigte Inhalt kann entlang der Timeline aktualisiert werden.
**! Wichtig: ** Da die Funktion "Widget" nur in "SwiftUI" implementiert werden kann, kann das Wesentliche von "Widget" als "SwiftUI" -Ansicht bezeichnet werden, die sich je nach Zeitachse ändert.
Nachdem Sie ein neues Multi-Plattform-Projekt mit "SwiftUI" erstellt haben, fügen Sie "Widget Extension" hinzu. Übrigens können Sie in einer App mehrere Widget-Erweiterungen hinzufügen.
Xcode → Datei → Neu → Ziel → Widget-Erweiterung Wenn das WidgetDemoW-Ziel erfolgreich hinzugefügt wurde, wird standardmäßig die Zeitansicht angezeigt.
In der Klasse widgetDemoW.swift ist die Markierung "@ main" der Eingang zu "Widget".
struct widgetDemoWEntryView : View {
var entry: Provider.Entry
var body: some View {
Text(entry.date, style: .time)
}
}
@main
struct widgetDemoW: Widget {
let kind: String = "widgetDemoW"
var body: some WidgetConfiguration {
IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider()) { entry in
widgetDemoWEntryView(entry: entry)
}
.configurationDisplayName("My Widget")
.description("This is an example widget.")
.supportedFamilies([.systemMedium])
}
}
--configurationDisplayName
ist der Anzeigename von Widget
, wenn der Benutzer das Widget
der App hinzufügt oder bearbeitet (da eine App mehrere Widget
s enthalten kann).
-- description
ist die Beschreibung von Widget
--supportedFamilies
ist die Surpot-Größe, und standardmäßig sind groß, mittel und klein alle Surpots.
** Anbieter ** ist das Objekt, das die Zeitachse für die Aktualisierung des Widgets bestimmt. Das System kann den Aktualisierungsprozess optimieren, indem es zukünftige Zeit für die Aktualisierung des Widgets bereitstellt. ** EntryView ** von widgetDemoWEntryView ist die Ansicht, die tatsächlich angezeigt wird.
Sie können diese Anwendung starten, indem Sie auf "Widget" klicken. Halten Sie "Widget" gedrückt, um die Bearbeitung zu starten.
Aktualisierungen von "Widget" werden vollständig von "WidgetCenter" gesteuert. Entwickler können die Widget-Ansicht nicht aktiv über die API aktualisieren. Sie können das Widget Center nur benachrichtigen, dass die Zeitleiste aktualisiert werden muss.
Auf dem System gibt es zwei Möglichkeiten, um das Neuladen der Timeline voranzutreiben. System Reloads
und App-Driven Reloads
.
** Hinweis: ** Beim erneuten Laden der Timeline wird "Widget" nicht direkt aktualisiert, aber "WidgetCenter" fordert "Widget" für die nächste Datenstufe zurück. Der "Anbieter" in der Zeitleiste ist das Objekt, das diese Daten bereitstellt.
Die vom "Anbieter" in der Zeitleiste bereitgestellten Daten bestehen aus zwei Teilen. Eines ist "TimelineEntry" und das andere ist "ReloadPolicy".
TimelineEntry
ist die Ansichtsinformation und der Zeitpunkt, zu dem Widget
unter einem bestimmten Zeitknoten angezeigt werden soll.
"ReloadPolicy" ist die Zeitleistenaktualisierungsrichtlinie für den nächsten Zeitraum. Es gibt drei Arten.
** atEnd **: Zeigt an, dass die Zeitleiste aktualisiert wird, wenn die letzte Zeitscheibe erreicht ist. ** atAfter **: Bezieht sich auf regelmäßige Updates nach einer bestimmten Zeit. ** nie **: Das bedeutet, dass Sie in Zukunft nicht mehr aktualisieren müssen. Wenn der letzte "Eintrag" angezeigt wird, stoppt er beim letzten "Eintrag" ohne Aktualisierung.
Zusätzlich zum Starten der App kann "Widget" auch mehrere Schaltflächen enthalten, die zu verschiedenen Seiten wechseln (nur mittelgroßes / großes "Widget").
Statische Anzeige
struct widgetDemoWEntryView : View {
var entry: Provider.Entry
var body: some View {
HStack {
Text("In diesem Artikel werde ich die Widget-Funktion von iOS14 vorstellen und implementieren.-20201017")
.foregroundColor(.black)
VStack {
Image("widgetPic")
.overlay(RoundedRectangle(cornerRadius: 10)
.stroke(Color.purple, lineWidth: 3))
.shadow(radius: 10)
.cornerRadius(10.0)
Text(entry.date, style: .time)
}
.padding()
}
.padding()
}
}
Anzeige entlang der Timeline
import WidgetKit
import SwiftUI
import Intents
struct Provider: IntentTimelineProvider {
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date(), text: "Es kommt von weit her. Es macht wieder keinen Spaß.", configuration: ConfigurationIntent())
}
func getSnapshot(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (SimpleEntry) -> ()) {
let entry = SimpleEntry(date: Date(), text: "Es kommt von weit her. Es macht wieder keinen Spaß.", configuration: configuration)
completion(entry)
}
func getTimeline(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
var entries: [SimpleEntry] = []
//Generieren Sie eine Zeitleiste mit 60 Einträgen in stündlichen Abständen ab dem aktuellen Datum
let currentDate = Date()
var textArray = [String]()
for i in 0..<60 {
textArray.append("Es kommt von weit her. Es macht wieder keinen Spaß. Zeitleiste: \(i)")
}
for minOffset in 0 ..< 60 {
let entryDate = Calendar.current.date(byAdding: .minute, value: minOffset, to: currentDate)!
let entryText = textArray[minOffset]
let entry = SimpleEntry(date: entryDate, text: entryText, configuration: configuration)
entries.append(entry)
}
let timeline = Timeline(entries: entries, policy: .atEnd)
completion(timeline)
}
}
struct SimpleEntry: TimelineEntry {
let date: Date
let text: String
let configuration: ConfigurationIntent
}
struct widgetDemoWEntryView : View {
var entry: Provider.Entry
var body: some View {
HStack {
Text(entry.text)
.foregroundColor(.black)
VStack {
Image("widgetPic")
.overlay(RoundedRectangle(cornerRadius: 10)
.stroke(Color.purple, lineWidth: 3))
.shadow(radius: 10)
.cornerRadius(10.0)
Text(entry.date, style: .time)
}
.padding()
}
//Behandeln Sie auf der Anwendungsseite die URL über onOpenURL und realisieren Sie die Aktion zum Übergang zu einem bestimmten Bildschirm, indem Sie auf Widget tippen
.widgetURL(URL(string: "widgetdemo://go2secondview"))
.padding()
}
}
@main
struct widgetDemoW: Widget {
let kind: String = "widgetDemoW"
var body: some WidgetConfiguration {
IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider()) { entry in
widgetDemoWEntryView(entry: entry)
}
.configurationDisplayName("My Widget")
.description("This is an example widget.")
.supportedFamilies([.systemMedium])
}
}
struct widgetDemoW_Previews: PreviewProvider {
static var previews: some View {
widgetDemoWEntryView(entry: SimpleEntry(date: Date(), text: "Es kommt von weit her. Es macht wieder keinen Spaß.", configuration: ConfigurationIntent()))
.previewContext(WidgetPreviewContext(family: .systemMedium))
}
}
Das Goku-Symbol wird statisch angezeigt und aktualisiert den Inhalt und die Zeit des Arguments in Schritten von 1 Minute.
Die Idee von "WidgetKit" ist sehr gut, aber aufgrund der Leistung des Betriebssystems und des Stromverbrauchs kann "Widget" keine Videos und dynamischen Bilder anzeigen. Ich denke jedoch, dass wenn Sie es gut verwenden, es definitiv die Qualität der Anwendung verbessern wird, also hoffe ich, dass ein besseres "Widget" herauskommt!
Recommended Posts