Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
507 views
in Technique[技术] by (71.8m points)

ios - Pass data entered in a UIView to a Widget

I try to implement a simple pattern on Widgets:

  • get a textField in the app;
  • have the Widget updated when textField is changed.

App is UIKit (not SwiftUI). I've read here that I could pass it through UserDefaults,

How to pass uiviewcontroller data to swiftui widget class

and also through a shared singleton. I tried but couldn't make it work.

What I tried:

  • Create a singleton to hold the data to pass:
    class Util {
        
        class var shared : Util {
            struct Singleton {
                static let instance = Util()
            }
            return Singleton.instance;
        }
        
        var globalToPass = "Hello"
    }
  • shared the file between the 2 targets App and WidgetExtension
  • In VC, update the singleton when textField is changed and ask for widget to reload timeline
    @IBAction func updateMessage(_ sender: UITextField) {
       
      Util.shared.globalToPass = valueToPassLabel.text ?? "--"
      WidgetCenter.shared.reloadTimelines(ofKind: "WidgetForTest")
      WidgetCenter.shared.reloadAllTimelines()
    }

Problem : Widget never updated its message field

Here is the full widget code at this time:

import WidgetKit
import SwiftUI

struct LoadStatusProvider: TimelineProvider {
    
    func placeholder(in context: Context) -> SimpleEntry {
        
        SimpleEntry(date: Date(), loadEntry: 0, message: Util.shared.globalToPass)
    }

    func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
        
        let entry = SimpleEntry(date: Date(), loadEntry: 0, message: Util.shared.globalToPass)
        completion(entry)
    }

    func getTimeline(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 minuteOffset in 0 ..< 2 {
            let entryDate = Calendar.current.date(byAdding: .minute, value: 5*minuteOffset, to: currentDate)!
            let entry = SimpleEntry(date: entryDate, loadEntry: minuteOffset, message: Util.shared.globalToPass)
            entries.append(entry)
        }
        let timeline = Timeline(entries: entries, policy: .atEnd)
        completion(timeline)
    }
}

struct SimpleEntry: TimelineEntry {
    let date: Date
    let loadEntry: Int
    let message: String
}

struct WidgetForTestNoIntentEntryView : View {
    var entry: LoadStatusProvider.Entry
    var body: some View {
        let formatter = DateFormatter()
        formatter.timeStyle = .medium
        let dateString = formatter.string(from: entry.date)
        return
            VStack {
                Text(String(entry.message))
                HStack {
                    Text("Started")
                    Text(entry.date, style: .time)
                }
                HStack {
                    Text("Now")
                    Text(dateString)
                }
                HStack {
                    Text("Loaded")
                    Text(String(entry.loadEntry))
                }
            }
    }
}
@main
struct WidgetForTestNoIntent: Widget {
    let kind: String = "WidgetForTestNoIntent"
    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind, provider: LoadStatusProvider()) { entry in
            WidgetForTestNoIntentEntryView(entry: entry)
        }
        .configurationDisplayName("My Widget")
        .description("This is an example widget.")
    }
}

struct WidgetForTestNoIntent_Previews: PreviewProvider {
    static var previews: some View {
        
        WidgetForTestNoIntentEntryView(entry: SimpleEntry(date: Date(), loadEntry: 0, message: "-"))
            .previewContext(WidgetPreviewContext(family: .systemSmall))
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...