You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中如何用Rune模型UUID更新拖拽视图UUID变量

SwiftUI拖拽功能实现问题解决方案

问题描述

我是SwiftUI新手,不确定能不能实现这个需求:用一款依赖UUID识别拖拽项的Swift拖拽包,实现元素拖拽到指定区域。我通过Rune模型(代码如下)从JSON加载数据,用LazyVGrid展示多个实例,每个实例自带runeid(UUID)。我需要把选中实例的runeid赋值给runeofday变量,传入DragView的id参数,这样就能在drop zone捕获拖拽项,用来后续填充数据(比如卡片翻转)。但试了多种变量类型,这个UUID变量还是没法更新。如果有不用这个包的更好方案也可以接受。

相关代码

Rune模型代码

// MARK: - Rune MODEL

struct Rune: Codable, Identifiable, Comparable  {
    static func < (lhs: Rune, rhs: Rune) -> Bool {
        lhs.title < rhs.title
    }
    
    let runeid = UUID()
    var id: Int
    var title: String
    var headline: String
    var image: String
    var pronunciation: String
    var sound: String
    var aett: String
    var god: String
    var knownas: [String]
    var keywords: [String]
    var translation: String
    var magick: [String]
    var gallery: [String]
    var meanings: [String]
    var runelore: [String]
    var poeticedda: [String]
}

LazyVGrid展示代码

LazyVGrid(columns: columns, spacing: 5) {
    ForEach(runes) { rune in
        RuneFrontView(rune: rune, width: width, height: height, degree: $frontDegree)
        RuneBackView(rune: rune, width: width, height: height, degree: $backDegree)
        
        switch rune.id {
        case 1:
            Text("rune 1")
//            runeofday = rune.runeid
        case 2:
            Text("rune 2")
//          runeofday = rune.runeid
        case 3:
            Text("rune 3")
//           runeofday = rune.runeid
        case 4:
            Text("rune 4")
//            runeofday = rune.runeid
        case 5:
            Text("rune 5")
//            runeofday = rune.runeid
        case 6:
            Text("rune 6")
//            runeofday = rune.runeid
        default:
            Text("rune default")
        } //:END OF SWITCH
    }.onTapGesture {
        flipCard ()
    }//: END OF ON TAP
}//: END OF LAZY V GRID

DragView代码

DragView(id: runeofday) { dragInfo in
    Text(dragInfo.isDragging ? "Im being dragged" : "Drag me 1")
        .padding()
        .background{
            Color.mint
        } //:END OF BACK GROUND
}

问题排查与修复(第三方包方案)

  1. 确保状态变量类型正确:runeofday必须是可绑定的状态变量,用@State或@Binding声明:
@State private var runeofday: UUID? = nil
  1. 修正Tap事件绑定范围:当前onTapGesture加在ForEach外层,点击任意网格项都会触发同一个事件,无法定位具体rune。需要把onTapGesture移到每个rune的视图容器内:
ForEach(runes) { rune in
    VStack {
        RuneFrontView(rune: rune, width: width, height: height, degree: $frontDegree)
        RuneBackView(rune: rune, width: width, height: height, degree: $backDegree)
        switch rune.id {
            // 你的switch代码
        }
    }
    .onTapGesture {
        runeofday = rune.runeid
        flipCard()
    }
}

原生SwiftUI拖拽方案(推荐)

无需依赖第三方包,用SwiftUI原生Drag&Drop实现更稳定:

1. 添加拖拽源到每个Rune项

ForEach(runes) { rune in
    VStack {
        RuneFrontView(rune: rune, width: width, height: height, degree: $frontDegree)
        RuneBackView(rune: rune, width: width, height: height, degree: $backDegree)
        switch rune.id {
            // 你的switch代码
        }
    }
    .onDrag {
        // 将runeid转为字符串作为拖拽数据
        NSItemProvider(object: rune.runeid.uuidString as NSString)
    }
    .onTapGesture {
        flipCard()
    }
}

2. 创建投放区域

@State private var selectedRuneId: UUID? = nil

VStack {
    Text(selectedRuneId != nil ? "已选中符文ID: \(selectedRuneId!.uuidString)" : "拖拽符文到这里")
        .padding()
        .background(Color.mint)
}
.onDrop(of: [.text], delegate: DropZoneDelegate(selectedRuneId: $selectedRuneId))

3. 实现DropDelegate处理投放逻辑

class DropZoneDelegate: DropDelegate {
    @Binding var selectedRuneId: UUID?
    
    init(selectedRuneId: Binding<UUID?>) {
        _selectedRuneId = selectedRuneId
    }
    
    func performDrop(info: DropInfo) -> Bool {
        guard let item = info.itemProviders(for: [.text]).first else { return false }
        item.loadObject(ofClass: NSString.self) { [weak self] value, error in
            guard let uuidString = value as? String, let uuid = UUID(uuidString: uuidString) else { return }
            DispatchQueue.main.async {
                self?.selectedRuneId = uuid
                // 在这里触发卡片翻转等后续操作
            }
        }
        return true
    }
}

内容的提问来源于stack exchange,提问作者brandon aho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 04:50:33