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.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
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
}
}
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 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)
}
}
}
}
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'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()
}
}
}
}
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?
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
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?