[SWIFT] Essayez d'implémenter la fonction Widget iOS14

Dans cet article, je présenterai et implémenterai la fonction Widget d'iOS14.

environnement OS:Catlina 10.15.4 Xcode:12.2 beta2

1, qu'est-ce que Widget

Apple a fourni une API qui vous permet d'accéder à des applications avec des fonctions simples telles que des calendriers et des minuteries au centre de notification qui apparaît lorsque vous glissez vers la gauche depuis l'écran d'accueil depuis ʻiOS 8, mais avec ʻiOS 14 l'écran d'accueil Il est maintenant possible d'afficher cela. La fonctionnalité a encore été augmentée et le contenu affiché peut être mis à jour le long de la chronologie.

**! Important: ** Puisque la fonction Widget ne peut être implémentée que dans SwiftUI, l'essence de Widget peut être considérée comme une vue SwiftUI qui change en fonction de la chronologie.

2, ordre de montage

Extension de widget ajoutée

Après avoir créé un nouveau projet multi-plateforme avec SwiftUI, ajoutez Widget Extension. En passant, vous pouvez ajouter plusieurs extensions de widget dans une seule application.

Xcode → Fichier → Nouveau → Cible → Extension du widget Si la cible widgetDemoW est ajoutée avec succès, la vue temporelle sera affichée par défaut.

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

Entrée du widget

Dans la classe widgetDemoW.swift, la marque @ main est l'entrée de 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 est le nom d'affichage de Widget lorsque l'utilisateur ajoute ou modifie le Widget de l'application (car il peut y avoir plusieurs Widgets dans une application). -- description est la description de Widget --supportedFamilies est la taille du surpot, et par défaut, grand, moyen et petit sont tous des surpots.

** provider ** est l'objet qui détermine la chronologie de la mise à jour de Widget. Le système peut optimiser le processus de mise à jour en fournissant le temps futur de mettre à jour le "Widget". ** EntryView ** de widgetDemoWEntryView est la vue qui est réellement affichée.

2020-10-17 16.39.39.png 2020-10-17 16.39.39.png 2020-10-17 16.39.39.png Vous pouvez démarrer cette application en cliquant sur «Widget». Appuyez et maintenez Widget pour commencer l'édition.

3, personnalisez le contenu d'affichage du widget

Les mises à jour de «Widget» sont entièrement contrôlées par «WidgetCenter». Les développeurs ne peuvent pas mettre à jour activement la vue "Widget" via l'API. Vous pouvez uniquement informer le Widget Center que la chronologie doit être mise à jour. Sur le système, il offre deux façons de piloter le rechargement de la chronologie. System Reloads et ʻApp-Driven Reloads`.

** Remarque: ** Le rechargement de la chronologie ne met pas directement à jour Widget, mais WidgetCenter récupère Widget pour la prochaine étape de données. Le «fournisseur» dans la chronologie est l'objet qui fournit ces données.

Il y a deux parties aux données fournies par le «fournisseur» dans la chronologie. L'un est «TimelineEntry» et l'autre est «ReloadPolicy».

TimelineEntry est les informations de vue et le point dans le temps que Widget doit afficher sous un nœud de temps particulier. ReloadPolicy est la politique de mise à jour de la chronologie au cours de la période suivante. Il existe trois types.

** atEnd **: indique que la chronologie sera mise à jour lorsque la dernière tranche horaire sera atteinte. ** atAfter **: fait référence aux mises à jour régulières après une certaine période. ** jamais **: cela signifie que vous n'avez pas besoin de mettre à jour à l'avenir. Lorsque la dernière «Entrée» est affichée, elle s'arrêtera à la dernière «Entrée» sans mise à jour.

En plus de lancer l'application, Widget peut également contenir plusieurs boutons qui font la transition vers différentes pages (taille moyenne / grande Widget uniquement).

Exemple de mise en œuvre 1

Affichage statique

struct widgetDemoWEntryView : View {
    var entry: Provider.Entry

    var body: some View {
        HStack {
            Text("Dans cet article, je présenterai et implémenterai la fonction Widget d'iOS14.-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()
    }
}

Affichage réel

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

Exemple de mise en œuvre 2

Afficher le long de la chronologie

import WidgetKit
import SwiftUI
import Intents

struct Provider: IntentTimelineProvider {
    func placeholder(in context: Context) -> SimpleEntry {
        SimpleEntry(date: Date(), text: "Il vient de loin. Ce n'est plus amusant.", configuration: ConfigurationIntent())
    }

    func getSnapshot(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (SimpleEntry) -> ()) {
        let entry = SimpleEntry(date: Date(), text: "Il vient de loin. Ce n'est plus amusant.", configuration: configuration)
        completion(entry)
    }

    func getTimeline(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
        var entries: [SimpleEntry] = []

        //Générer une chronologie composée de 60 entrées toutes les heures, à partir de la date actuelle
        let currentDate = Date()
        var textArray = [String]()
        for i in 0..<60 {
            textArray.append("Il vient de loin. Ce n'est plus amusant. chronologie: \(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()
        }
        //Du côté de l'application, gérez l'URL via onOpenURL et réalisez l'action de transition vers un écran spécifique en appuyant sur Widget
        .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: "Il vient de loin. Ce n'est plus amusant.", configuration: ConfigurationIntent()))
            .previewContext(WidgetPreviewContext(family: .systemMedium))
    }
}


L'icône Goku s'affiche de manière statique et met à jour le contenu et l'heure de l'argument par incréments de 1 minute.

Affichage réel

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

4, la fin

L'idée de WidgetKit est très bonne, mais en raison des performances du système d'exploitation et de la consommation d'énergie, Widget ne peut pas afficher de vidéo et d'images dynamiques. Cependant, je pense que si vous l'utilisez bien, cela améliorera certainement la qualité de l'application, donc j'espère qu'un meilleur Widget sortira!

Recommended Posts

Essayez d'implémenter la fonction Widget iOS14
Essayez d'implémenter une fonction de connexion avec Spring-Boot
Essayez d'implémenter la fonction de connexion avec Spring Boot
Essayez d'implémenter Yuma dans Ruby
[Java] Essayez de mettre en œuvre à l'aide de génériques
Essayez d'implémenter Yuma en Java
Essayez d'implémenter l'ajout n-aire en Java
Comment implémenter TextInputLayout avec la fonction de validation
Comment mettre en œuvre la fonction de chapelure avec Gretel
[Android] Implémentez rapidement la fonction pour afficher le mot de passe
[Pour les débutants] Comment implémenter la fonction de suppression
Flux pour implémenter la fonction de publication d'images à l'aide d'ActiveStorage
Essayez d'implémenter TCP / IP + NIO avec JAVA
Suite ・ Flux pour implémenter la fonction de publication d'image à l'aide d'ActiveStorage
Essayez de mettre en œuvre à l'aide de l'API de recherche de produits Rakuten (facile)
14 Correspond à une expression de fonction
J'ai essayé d'implémenter la fonction similaire par communication asynchrone
Je souhaite implémenter une fonction d'édition des informations produit ~ part1 ~
[IOS] Ce que vous devez savoir avant de créer un widget
Implémenter la fonction d'application dans Rails
Essayez Spring Boot de 0 à 100.
Java pour jouer avec Function
Comment ajouter la fonction ActionText
Implémenter la fonction de catégorie en utilisant l'ancêtre
[iOS] Comment lire Carthage
[Rails] Comment mettre en œuvre le scraping
[Rails] Implémenter la fonction de publication d'images
[Java] Comment implémenter le multithreading
[Rails] Un moyen simple d'implémenter une fonction d'auto-introduction dans votre profil
J'ai essayé d'implémenter le traitement Ajax de la fonction similaire dans Rails
J'ai essayé d'implémenter la fonction de prévisualisation d'image avec Rails / jQuery