MST

星途 面试题库

面试题:Swift中SwiftUI如何实现基础的拖拽与放置功能

在SwiftUI里,若要实现一个简单的文本视图从一个区域拖拽到另一个区域并放置成功,描述实现该功能所需的关键步骤,包括视图修饰符和相关协议的使用,同时编写示例代码展示其基础实现。
23.2万 热度难度
编程语言Swift

知识考点

AI 面试

面试题答案

一键面试

关键步骤

  1. 使用DragGesture:
    • 可以通过gesture视图修饰符将DragGesture添加到文本视图上。
    • 配置DragGestureonChangedonEnded回调,onChanged用于在拖拽过程中更新文本视图的位置,onEnded用于判断是否放置成功并进行相应处理。
  2. 实现相关协议:
    • 这里主要涉及自定义逻辑来判断放置成功,例如判断放置区域的边界等,不需要特定的SwiftUI内置协议来专门处理这个简单的拖拽放置逻辑,但在复杂场景下可能会用到DropDelegate等相关协议(如果需要处理更复杂的拖放交互,如跨应用拖放等)。

示例代码

import SwiftUI

struct DraggableTextView: View {
    @State private var offset = CGSize.zero
    @State private var isSuccess = false
    let dropZoneSize: CGFloat = 200
    let text = "Drag me"

    var body: some View {
        VStack {
            Text(text)
               .padding()
               .background(Color.blue)
               .foregroundColor(.white)
               .cornerRadius(10)
               .offset(x: offset.width, y: offset.height)
               .gesture(
                    DragGesture()
                       .onChanged { value in
                            offset = value.translation
                        }
                       .onEnded { value in
                            let endX = value.location.x
                            let endY = value.location.y
                            // 简单判断是否放置在特定区域(这里假设一个正方形区域在屏幕中心)
                            let centerX = UIScreen.main.bounds.midX
                            let centerY = UIScreen.main.bounds.midY
                            if endX >= centerX - dropZoneSize / 2 && endX <= centerX + dropZoneSize / 2 &&
                                endY >= centerY - dropZoneSize / 2 && endY <= centerY + dropZoneSize / 2 {
                                isSuccess = true
                            } else {
                                withAnimation {
                                    offset = .zero
                                }
                            }
                        }
                )
            if isSuccess {
                Text("Drop success!")
                   .padding()
                   .background(Color.green)
                   .foregroundColor(.white)
                   .cornerRadius(10)
            }
            Rectangle()
               .frame(width: dropZoneSize, height: dropZoneSize)
               .foregroundColor(Color.gray.opacity(0.3))
               .position(x: UIScreen.main.bounds.midX, y: UIScreen.main.bounds.midY)
        }
    }
}

struct DraggableTextView_Previews: PreviewProvider {
    static var previews: some View {
        DraggableTextView()
    }
}