将在 UIView 中输入的数据传递给小部件

问题描述

我尝试在小部件上实现一个简单的模式:

  • 在应用中获取一个 textField;
  • 在更改 textField 时更新小部件。

应用程序是 UIKit(不是 SwiftUI)。 我在这里读到我可以通过 UserDefaults 传递它,

How to pass uiviewcontroller data to swiftui widget class

并且还通过共享单例。我试过了,但不能让它工作。

我尝试了什么:

  • 创建一个单例来保存要传递的数据:
    class Util {
        
        class var shared : Util {
            struct Singleton {
                static let instance = Util()
            }
            return Singleton.instance;
        }
        
        var globalToPass = "Hello"
    }
  • 在 2 个目标 App 和 WidgetExtension 之间共享文件
  • 在 VC 中,当 textField 更改时更新单例并要求小部件重新加载时间线
    @IBAction func updateMessage(_ sender: UITextField) {
       
      Util.shared.globalToPass = valuetoPassLabel.text ?? "--"
      WidgetCenter.shared.reloadTimelines(ofKind: "WidgetForTest")
      WidgetCenter.shared.reloadAllTimelines()
    }

问题:小部件从未更新其消息字段

这是此时的完整小部件代码

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(),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(),message: "-"))
            .previewContext(WidgetPreviewContext(family: .systemSmall))
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)