Learn Courses My Dashboard

SwiftUI Drag and Drop - single app

I have an app I created just to try to make drag and drop work between two VStacks. I have a working view in my program where I have an HStack, Vstack, Divider, VStack, which works fine to copy and past between the text fields in each, but what I want instead is Drag from Column 1 and Drop into Column 2.

The problem code follows, I have been working on this watching tutorials, etc and trying to make this work for a couple of days. Most of the examples use Url’s or Images, but I just am trying to drag text fields.

I created a plain SwiftUI project and only added/changed the one view shown below.

Any Hints/Tips/Examples/Ideas appreciated. Not wedding to this approach. If drop could work without the delegate, that would be great? Drag seems relatively straight forward.

//
// AllViews.swift
// dragdroptest
//
// Created by Sandra K Cureton on 7/19/21.
//

import Foundation
import SwiftUI

// =================================================================
struct MemberNamesView : View {

@State  var memberNames = ["Sandy", "Wendy", "Rosalie"]

var body: some View {
    
    VStack {
        Text("Member Names")
        ForEach(memberNames, id: \.self) { name in
            Text(name)
                .onDrag {
                    NSItemProvider(object: name as NSString)
                    
                }
        }
    }
    .navigationBarTitle("Club Members")
}
}

// ====================================================================
struct PlayerNamesView: View {
@Binding var playername: String?
@Binding var playernames: [String?]

@State var myplayernames = [String](arrayLiteral: "111111", "22222", "33333", "44444 ", "55555 ", "66666 ", " 77777", "88888 ", "99999 ", "101111", "11222", "12333", "13444 ", "141111", "15222", "16333")
@State var pname = String("Sandy")
@State var pnames = []
var body: some View {
    VStack {
        
        Text("Player Names")
        ForEach(myplayernames, id: \.self) { playername in
            Text(verbatim: playername ?? " ")
        }
   //     .onInsert(of: ["public.text"], perform: drop)
        .onDrop(
            of: ["public.text"],
            delegate: PlayerNames(names: playernames) )
          //  delegate: PlayerNames(name: Binding(get: { name }, set: {name = $0 }) ) )

**error occurs here as well -Cannot convert value of type ‘[String?]’ to expected argument type ‘Binding<[String]>’

I have been able to correct this before with the commented text below, but this problem is probably secondary. I have been trying try a lot of ways trying State vars and Binding but what I want os one text field dragged to one text field, both are in arrays of text fields in for each loops in VStacks **
}
.navigationBarTitle(“Players”)
}
/*
private func drop(at index: Int, _ items: [NSItemProvider]) {
for item in items {
_ = item.loadObject(ofClass: NSString.self) { text, _ in
DispatchQueue.main.async {
text.map { self.playernames.insert(contentsOf: $0, at: index) }
}
}
}
} // end of private function drop
}*/

// ================================================ DROP DELEGATE
struct PlayerNames: DropDelegate { **
@Binding var names: [String]

func performDrop(info: DropInfo) -> Bool {

    let items = info.itemProviders(for: ["public.text"])
    for item in items {
        _ = item.loadObject(ofClass: NSString.self) { name, _ in
            if let name = name {
                DispatchQueue.main.async {
                    self.names.insert(names[$0], at: 0)

**Error occurs in one of the two above lines it either complains in the first line, that there is no exact matches in call to instance method ‘async’ or
in the second line it complains no insert method exists. I expect the error messages are imprecise.
**
}
}
}
}

    return true
}

} // End Drop Delegate

struct MyView : View {
@State var players: [String]
@State var members: [String]

var body: some View {

    HStack {
        Text("member names") //MemberNamesView
        Divider()
        Text("player names ")// PlayerNamesView
    }
}

}
/*
struct MyView_Previews: PreviewProvider {
static var previews: some View {
MyView()
}
} */
}