SwiftUI - MacOS: Dragging rows in a List using MagnificationGesture is not recognized

Viewed 20

I am making an application for macos using the SwiftUI framework, I am trying to create a List or a Table, with the ability to use MagnificationGesture, but unfortunately the dragging of the list/table does not work. It also does not work, or better to say, the recognition of buttons inside the list is shifted. Any ideas how this can be implemented?

short video about the problem

import SwiftUI

struct ContentView: View {
    
    struct User: Identifiable, Hashable {
        let id: Int
        var name: String
        var score: Int
    }
    
    @State private var users = [
        User(id: 1, name: "Taylor Swift", score: 90),
        User(id: 2, name: "Justin Bieber", score: 80),
        User(id: 3, name: "Adele Adkins", score: 85)
    ]
    
    @State private var sortOrder = [KeyPathComparator(\User.name)]
    @State private var selection: User.ID?
    
    @State var mainFrame = CGSize(width: 400, height: 400)
    @State var scale: CGFloat = 1.0
    @State var lastScaleValue: CGFloat = 1.0
    
    var body: some View {
        
        let magnificationGesture = MagnificationGesture()
            .onChanged { val in
                let delta = val / self.lastScaleValue
                self.lastScaleValue = val
                var newScale = self.scale * delta
                if newScale < 1.0 {
                    newScale = 1.0
                }
                scale = newScale
            }.onEnded { val in
                lastScaleValue = 1
            }
        
        ScrollView([.vertical, .horizontal], showsIndicators: false) {
            ZStack {
                Rectangle()
                    .foregroundColor(.clear)
                    .frame(width: mainFrame.width * scale, height: mainFrame.height * scale, alignment: .center)
                    .padding(40)
                
                VStack {
                    
                    // doesn't work
                    List {
                        ForEach(users, id: \.self) { item in
                            Text(item.name)
                        }
                        .onMove(perform: move)
                    }.border(.red)
                    
                    // doesn't work
                    List {
                        Button("test - 1", action: {print(1)})
                        Button("test - 2", action: {print(2)})
                        Button("test - 3", action: {print(3)})
                    }.border(.red)
                    
                    // doesn't work
                    Table(users, selection: $selection, sortOrder: $sortOrder) {
                        TableColumn("Name", value: \.name)
                        TableColumn("Score", value: \.score) { user in
                            Text(String(user.score))
                        }
                    }.border(.red)
                    .onChange(of: sortOrder) { newOrder in
                        users.sort(using: newOrder)
                    }
                }
                .frame(width: mainFrame.width, height: mainFrame.height)
                .background(Rectangle().fill(Color.white).shadow(radius: 3))
                .scaleEffect(scale)
                .gesture(magnificationGesture)
            }
        }
        .background(Color.gray.edgesIgnoringSafeArea(.all))
    }
    
    func move(from source: IndexSet, to destination: Int) {
        users.move(fromOffsets: source, toOffset: destination)
    }
}
0 Answers
Related