Post

Replies

Boosts

Views

Activity

NSTableViewDiffableDataSource + Drag and Drop
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     }      }
Topic: UI Frameworks SubTopic: AppKit Tags:
1
1
1.1k
Jun ’22
TextField slowing list when changing model property in task
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)             }         }     } }
0
0
791
Dec ’22
UIViewRepresentable never dismantled on deletion (MEMORY LEAK)
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)             }         }     } }
1
2
1.5k
Feb ’23
UIHostingConfiguration + MainActor.assumeIsolated?
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() } } } }
1
0
485
Oct ’24
ScrollPosition.scrollTo(id:, anchor:) not behaving as expected
While trying the new ScrollPosition API I noticed that scrollTo(id: anchor:) behaves different than ScrollViewProxy.scrollTo(_: anchor:). Consider the following example: struct ContentView: View { @State private var position = ScrollPosition(edge: .top) var body: some View { NavigationStack { ScrollViewReader { proxy in ScrollView { VStack(spacing: 8) { ForEach(1..<100) { index in Text(verbatim: index.formatted()) .frame(maxWidth: .infinity) .background(.gray) .id(index) } } } .scrollPosition($position) .toolbar { ToolbarItemGroup(placement: .bottomBar) { Spacer() Button("50 (T)") { withAnimation { position.scrollTo(id: 50, anchor: .top) // proxy.scrollTo(50, anchor: .top) } } Button("50 (B)") { withAnimation { position.scrollTo(id: 50, anchor: .bottom) // proxy.scrollTo(50, anchor: .bottom) } } Spacer() } } } } } } The position methods don't align top and bottom edges, but the proxy ones do. Is this expected or is it a bug?
2
0
98
May ’25
Behavior of Image and ignoresSafeArea
Consider this 400x800 image: I would expect the background image in the following code to fill the entire screen: struct ContentView: View { var body: some View { VStack { } .frame(maxWidth: .infinity, maxHeight: .infinity) .background { Image(.background) .resizable() .scaledToFill() .ignoresSafeArea() } } } But there's a small gap in the bottom: Swapping the order of scaledToFill and ignoresSafeArea fills this gap: Image(.background) .resizable() .ignoresSafeArea() .scaledToFill() Why? Ignoring specific edges is more problematic: struct ContentView: View { var body: some View { VStack { } .statusBarHidden() .frame(maxWidth: .infinity, maxHeight: .infinity) .border(.black) .background { Image(.background) .resizable() .ignoresSafeArea(edges: .top) .scaledToFill() } } } My solution here was to use the Image as an overlay of a Rectangle. Rectangle() .overlay { Image(.background) .resizable() .scaledToFill() } .clipped() .ignoresSafeArea(edges: .top) Is there a better way to achieve this? I wonder if someone from SwiftUI Team could help me to better undestand Image behavior regardless ignoresSafeArea.
Topic: UI Frameworks SubTopic: SwiftUI
3
0
53
Jul ’25
PhaseAnimator without transition between phases
PhaseAnimator seems a good fit to play gifs in SwiftUI: struct ContentView: View { let frames = [UIImage(named: "frame-1")!, UIImage(named: "frame-2")!] var body: some View { PhaseAnimator(frames.indices) { index in Image(uiImage: frames[index]) } } } The problem is that by default, there's an opacity transition between phases. So I tried using transition(.identity): Image(uiImage: gif[index]) .transition(.identity) .id(index) It doesn't work. It stays frozen on the first frame. It does work if I set the transition to a small offset value: Image(uiImage: gif[index]) .transition(.offset(x: 0, y: 0.1)) .id(index) It does feel a bit hacky, though. Is this the expected behavior for .transition(.identity), or is it a bug?
1
0
86
Jul ’25