swift - SwiftUI 集成 UIKit(iOS 应用)中 @Binding 变量的奇怪行为
问题描述
我正在为我学校的课程开发一个应用程序,显示课程的描述以及显示约会的日历。我决定使用 KVKCalendar 作为日历的库。使用 SwiftUI 开发并将 KVKCalendar 库作为 UIKit 环境,我必须连接两个系统(使用 struct CalendarRepresentable
,请参阅代码)。
该应用程序的构造如下:我从内存中加载@ObservedObject
保存的对象,将其传递给一些子视图@Binding
,以便从课程目录中保存/删除新课程。在视图中所做的所有更改都会在所有其他视图中相应更新,但不幸的是TimetableView
,在与 struct 连接的 中没有CalendarRepresentable
。
问题:我想在保存新课程时更新日历(例如添加到courses
type 的数组中[Courses]
)。目前该结构CalendarRepresentable
正在按预期调用,makeUIView
但日历不再更新。特别是保存的课程courses
不是不断更新,而是以一种(显然)不一致的方式:在结构的某些函数CalendarRepresentable
中确实是最新的,而在其他一些函数(和子类)中则不是。请参阅我显示这些不一致发生的位置和情况的代码。
调用 UIKit-SwiftUI 接口的 View 代码: import SwiftUI import KVKCalendar
struct TimetableView: View {
@Binding var courses: [Courses]
let saveAction: () -> Void
var body: some View {
CalendarRepresentable(courses: $courses)
}
}
struct TimetableView_Previews: PreviewProvider {
static var previews: some View {
TimetableView(courses: .constant(Courses.data), saveAction: {})
}
}
接口代码:
import SwiftUI
import KVKCalendar
import EventKit
struct CalendarRepresentable: UIViewRepresentable{
@Binding var courses: [Courses]
var events = [Event]()
var calendar: CalendarView = {
print("Representable has been launched")
var style = Style()
//style of the calendar
//...
return CalendarView(frame: UIScreen.main.bounds, style: style)
}()
func updateUIView(_ uiView: CalendarView, context: Context ){
print("updateUIView has been called. Courses has \(courses.count) elements") // **Here courses has always the correct amount of elements**
calendar.dataSource = context.coordinator
calendar.delegate = context.coordinator
calendar.reloadData()
calendar.reloadInputViews()
print("updateUIView is finished")
}
public func passCourses() -> [Courses]{
print("Called passCourses with courses having \(courses.count) elements") //**Here courses has NOT the corrent amount of elements, i.e. after saving/deleting a course courses.count is different from what is printed in the previous function updateUIView**
return courses
}
func makeUIView(context: Context) -> CalendarView {
print("makeUIView has been called")
calendar.dataSource = context.coordinator
calendar.delegate = context.coordinator
calendar.reloadData()
return calendar
}
func makeCoordinator() -> Coordinator {
print("makeCoordinator")
return Coordinator(self)
}
class Coordinator: NSObject, CalendarDelegate, CalendarDataSource {
var events = [Event]()
var parent: CalendarRepresentable
func eventsForCalendar(systemEvents: [EKEvent]) -> [Event] {
print("eventsForCalendar called. In Coordinator \(events.count) events and \(parent.courses.count) courses") //**here courses are again not uptodate to the CalendarRepresentable' courses**
loadEvents { (events) in
self.events = events
}
return self.events
}
init(_ parent: CalendarRepresentable){
print("Initialize Coordinator")
self.parent = parent
super.init()
loadEvents { (events) in
self.events = events
self.parent.calendar.reloadData()
}
}
func eventsForCalendar() -> [Event] {
print("eventsForCalendar without parameter")
return events
}
func loadEvents(completion: ([Event]) -> Void) {
var events = [Event]()
print("loadEvents with courses having \(self.parent.courses.count) elements")//**here courses are again not uptodate to the CalendarRepresentable' courses**
var i: Int=0
for course in self.parent.passCourses() {
let isoDateStart = course.startEvent
let dateStartFormatter = ISO8601DateFormatter()
let isoDateEnd = course.endEvent
let dateEndFormatter = ISO8601DateFormatter()
var event = Event(ID: "\(i)")
event.start = dateStartFormatter.date(from: isoDateStart)!
event.end = dateEndFormatter.date(from: isoDateEnd)!
event.text = course.name
events.append(event)
i=i+1
}
completion(events)
}
}
}
保存课程(在另一个视图中完成)后控制台输出的示例(明显)不一致:
Representable has been launched
updateUIView has been called. Courses has 4 elements
eventsForCalendar called. In Coordinator 3 events and 3 courses
loadEvents with courses having 3 elements
Called passCourses with courses having 3 elements
updateUIView is finished
有谁知道发生了courses
什么?关于我应该如何解决问题的建议?
非常感谢您的时间和帮助!
解决方案
经过广泛的测试后,我发现问题在于,尽管外部结构已更改,但不知何故,协调器已被一位老父母调用。我不确定该行为的内部原因,但无论如何现在应该解决:courses
数据现在已成功传递给协调器。courses
但是,尽管正确触发发生了变化,但视图仍然不会自行更新updateUIView
。任何建议表示赞赏。
推荐阅读
- xamarin.forms - 使用回车键从条形码阅读器读取 Xamarin.Forms 条目给出空结果
- php - Laravel syncWithoutDetaching 额外字段
- c - CS50 pset4 滤镜“模糊
- angular - 未知错误:错误:没有为 src\main\ui\node_modules\uuid 找到有效的导出 main?
- php - FreeTDS + Doctrine 去除零小数
- express - 即使我调用 server.close(),Mocha 也不会退出
- html - 缺少有效的 YouTube API 密钥
- xml - 使用单个 XSLT 生成不同的输出文件
- sql - 查找表中每个实体的最大 N 值的最有效 SQL 查询是什么
- laravel - 在 Laravel 中执行 CRUD 的单个函数