I'm trying to use a SwiftUI view as UICalendarView decoration and I get Call to main actor-isolated instance method 'makeContentView()' in a synchronous nonisolated context; this is an error in the Swift 6 language mode in the following code:
class Coordinator: NSObject, UICalendarViewDelegate {
func calendarView(_ calendarView: UICalendarView, decorationFor dateComponents: DateComponents) -> UICalendarView.Decoration? {
.customView {
UIHostingConfiguration {
...
}
.makeContentView()
}
}
}
I've fixed using MainActor.assumeIsolated but is this the correct approach or is there a better one?
class Coordinator: NSObject, UICalendarViewDelegate {
func calendarView(_ calendarView: UICalendarView, decorationFor dateComponents: DateComponents) -> UICalendarView.Decoration? {
.customView {
MainActor.assumeIsolated {
UIHostingConfiguration {
...
}
.makeContentView()
}
}
}
}
Post
Replies
Boosts
Views
Activity
I'm using NSPersistentCloudKitContainer to sync CoreData to CloudKit public database but I have the problem that canUpdateRecord always returns true even for objects created by another iCloud user with _icloud role permission set to Read only. Am I missing something?
I have find out that a UIViewRepresentable, even with a simples UIView, seems to never be dismantled when deleted from a ForEach and this can cause serious crashes.
In the following example you can observe this behavior by deleting a row from the list. The dismantleUIView function of SomeUIViewRepresentable or the deinit of SomeUIView are never called.
Has anyone faced this and found a solution for it?
I have also filled a Feedback: FB11979117
class SomeUIView: UIView {
deinit {
print(#function)
}
}
struct SomeUIViewRepresentable: UIViewRepresentable {
func makeUIView(context: Context) -> SomeUIView {
let uiView = SomeUIView()
uiView.backgroundColor = .systemBlue
return uiView
}
func updateUIView(_ uiView: SomeUIView, context: Context) { }
static func dismantleUIView(_ uiView: SomeUIView, coordinator: Coordinator) {
print(#function)
}
}
struct Model: Identifiable {
let id = UUID()
}
struct ContentView: View {
@State var models = [Model(), Model(), Model(), Model(), Model()]
var body: some View {
List {
ForEach(models) { _ in
SomeUIViewRepresentable()
}
.onDelete {
models.remove(atOffsets: $0)
}
}
}
}
The TextField in the following code makes the List very lag when scrolling. Note that I'm not even changing the property used by TextField. I'm able to solve this by changing my model to a ObservableObject but I would like to keep as a struct if possible. Does anyone have any solution? Thanks!
struct Model: Identifiable {
let id = UUID()
var text: String = "Lorem Ipsum"
var bool = false
}
struct RowView: View {
@Binding var model: Model
var body: some View {
TextField("", text: $model.text)
.task {
try? await Task.sleep(for: .seconds(0.5))
model.bool.toggle()
}
}
}
struct ContentView: View {
@State var models = (1...100).map({ _ in Model() })
var body: some View {
List {
ForEach($models) { $model in
RowView(model: $model)
}
}
}
}
I was able to implement drag and drop with NSTableViewDiffableDataSource by subclassing and adding the missing methods. It works but the draggingSession willBeginAt method is never called so I can't provided a custom preview to the dragging. Any tips from AppKit developers or Apple engineers?
class ListCoordinator: NSTableViewDiffableDataSource<String, Int>, NSTableViewDelegate {
@objc func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? {
return NSPasteboardItem(pasteboardPropertyList: row.formatted(), ofType: .string)
}
@objc func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation {
return .move
}
@objc func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableView.DropOperation) -> Bool {
...
return true
}
@objc func tableView(_ tableView: NSTableView, draggingSession session: NSDraggingSession, willBeginAt screenPoint: NSPoint, forRowIndexes rowIndexes: IndexSet) {
// NEVER CALLED
}
}
Does any one know why onDelete method uses an IndexSet for delete operation? I couldn't find any way to delete more than one row from a List.