【问题标题】:Drag & drop to reorder for Text without using List/Form拖放以重新排序文本而不使用列表/表单
【发布时间】:2020-12-29 03:41:29
【问题描述】:

我已经使用 .gesture 来拖动文本。

我想要发生的是剩余的字母向右移动,这样 'g' 占据第一个位置,剩余的字母向右移动。但我不知道该怎么做。

struct TryingDrag: View {
    let letters = Array("Begin Saving")
    @State private var dragAmount = CGSize.zero
    
    var body: some View {
        HStack (spacing: 0) {
            ForEach(0..<letters.count) { index in
                let letter = String(letters[index])
                LettersDrag(letter: letter)
            }
        }
    }
}

struct LettersDrag: View {
    let letter: String
    @State private var dragAmount = CGSize.zero
    
    var body: some View {
        Text(letter).foregroundColor(.white)
            .padding(5)
            .font(.title)
            .background(Color.red)
            .offset(dragAmount)
            .animation(.spring())
            .gesture(
                DragGesture()
                    .onChanged {
                        dragAmount = $0.translation
                    }
                    
                    .onEnded { _ in
                        dragAmount = .zero
                    }
            )
    }
}

我希望它具有与下图类似的行为(但不使用列表/表单):

【问题讨论】:

    标签: swiftui hstack


    【解决方案1】:

    您可以使用onDragonDrop 来实现这一点。我不得不稍微改变你的结构并添加一个模型来处理你的字母数据。

    Asperi 很好地描述了拖放部分的工作原理here。 (这也是他的想法+代码,我只是根据你的情况进行了改编)

    import SwiftUI
    import UniformTypeIdentifiers
    
    struct LettersData: Identifiable, Equatable {
        
        let id: Int
        let letter: String
    }
    
    
    class Model: ObservableObject {
        
        @Published var letters: [LettersData] = []
    
        
        init(input: String) {
            let inputArray = Array(input).map(String.init)
            
            for i in 0..<inputArray.count {
                letters.append(LettersData(id: i, letter: inputArray[i]))
            }
        }
    }
    
    
    struct TryingDrag: View {
        
        @StateObject private var model = Model(input: "Begin Saving")
        @State private var dragging: LettersData?
        
        
        var body: some View {
            HStack (spacing: 0) {
                ForEach(model.letters) { letter in
                    LettersDrag(letter: letter.letter)
                        .onDrag {
                            self.dragging = letter
                            return NSItemProvider(object: String(letter.id) as NSString)
                        }
                        .onDrop(of: [UTType.text], delegate: DragRelocateDelegate(item: letter, listData: $model.letters, current: $dragging))
                }
            }
            .animation(.default, value: model.letters)
        }
    }
    
    
    struct LettersDrag: View {
        
        let letter: String
        
        
        var body: some View {
            Text(letter).foregroundColor(.white)
                .padding(5)
                .font(.title)
                .background(Color.red)
                .animation(.spring())
        }
    }
    
    
    struct DragRelocateDelegate: DropDelegate {
        
        let item: LettersData
        
        @Binding var listData: [LettersData]
        @Binding var current: LettersData?
    
        
        func dropEntered(info: DropInfo) {
            if item != current {
                let from = listData.firstIndex(of: current!)!
                let to = listData.firstIndex(of: item)!
                if listData[to].id != current!.id {
                    listData.move(fromOffsets: IndexSet(integer: from),
                        toOffset: to > from ? to + 1 : to)
                }
            }
        }
    
        
        func dropUpdated(info: DropInfo) -> DropProposal? {
            return DropProposal(operation: .move)
        }
    
        
        func performDrop(info: DropInfo) -> Bool {
            self.current = nil
            return true
        }
    }
    

    我希望这就是你想要的。

    【讨论】:

      猜你喜欢
      • 2012-05-08
      • 1970-01-01
      • 2012-05-31
      • 1970-01-01
      • 2010-10-22
      • 1970-01-01
      • 2012-06-19
      • 2010-12-28
      • 2020-04-05
      相关资源
      最近更新 更多