[SWIFT] Versuchen Sie, die iOS14-Widget-Funktion zu implementieren

In diesem Artikel werde ich die Widget-Funktion von iOS14 vorstellen und implementieren.

Umgebung OS:Catlina 10.15.4 Xcode:12.2 beta2

1, was ist Widget

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.

2, Montagereihenfolge

Widget-Erweiterung hinzugefügt

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.

スクリーンショット 2020-10-17 14.42.47.png スクリーンショット 2020-10-17 14.45.41.png

Widget-Eingang

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 Widgets 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.

2020-10-17 16.39.39.png 2020-10-17 16.39.39.png 2020-10-17 16.39.39.png Sie können diese Anwendung starten, indem Sie auf "Widget" klicken. Halten Sie "Widget" gedrückt, um die Bearbeitung zu starten.

3, passen Sie den Anzeigeinhalt des Widgets an

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").

Implementierungsbeispiel 1

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()
    }
}

Aktuelle Anzeige

スクリーンショット 2020-10-17 23.51.37.png

Implementierungsbeispiel 2

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.

Aktuelle Anzeige

2020-10-17 16.39.39.png 2020-10-17 16.39.39.png 2020-10-17 16.39.39.png

4, das Ende

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

Versuchen Sie, die iOS14-Widget-Funktion zu implementieren
Versuchen Sie, eine Anmeldefunktion mit Spring-Boot zu implementieren
Versuchen Sie, die Anmeldefunktion mit Spring Boot zu implementieren
Versuchen Sie, Yuma in Ruby zu implementieren
[Java] Versuchen Sie, mithilfe von Generika zu implementieren
Versuchen Sie, Yuma in Java zu implementieren
Versuchen Sie, n-ary Addition in Java zu implementieren
So implementieren Sie TextInputLayout mit Validierungsfunktion
So implementieren Sie die Brotkrumenfunktion mit gretel
[Android] Implementieren Sie schnell die Funktion zum Anzeigen des Passworts
[Für Anfänger] So implementieren Sie die Löschfunktion
Ablauf zur Implementierung der Image-Posting-Funktion mit ActiveStorage
Versuchen Sie, TCP / IP + NIO mit JAVA zu implementieren
Fortsetzung ・ Ablauf zur Implementierung der Image-Posting-Funktion mit ActiveStorage
14 Entspricht einem Funktionsausdruck
Ich habe versucht, die ähnliche Funktion durch asynchrone Kommunikation zu implementieren
Ich möchte eine Produktinformationsbearbeitungsfunktion ~ part1 ~ implementieren
[IOS] Was Sie wissen müssen, bevor Sie ein Widget erstellen
Implementieren Sie die Anwendungsfunktion in Rails
Versuchen Sie Spring Boot von 0 bis 100.
Java zum Spielen mit Function
So fügen Sie die ActionText-Funktion hinzu
Implementieren Sie die Kategoriefunktion mithilfe von Vorfahren
[iOS] Wie man Karthago liest
[Rails] So implementieren Sie Scraping
[Rails] Implementieren Sie die Image-Posting-Funktion
[Java] So implementieren Sie Multithreading
[Rails] Eine einfache Möglichkeit, eine Selbsteinführungsfunktion in Ihrem Profil zu implementieren
Ich habe versucht, die Ajax-Verarbeitung der ähnlichen Funktion in Rails zu implementieren
Ich habe versucht, die Bildvorschau mit Rails / jQuery zu implementieren