面试题答案
一键面试- 使
Person
适配拖拽与放置:- 让
Person
遵循Codable
协议,这样可以方便地对其进行编码和解码,以便在拖拽与放置过程中传输数据。 - 因为
Person
已经遵循Identifiable
协议,我们主要关注编码解码相关实现。
- 让
Draggable
协议实现:- 在SwiftUI中,我们使用
DragGesture
相关功能,通过设置onDrag
修饰符来实现拖拽。 - 对于
Person
类型,我们将其编码为Data
以便在拖拽中传递。
- 在SwiftUI中,我们使用
Droppable
协议实现:- 使用
DropDelegate
协议来处理放置操作。 - 在放置时,将接收到的
Data
解码回Person
实例,并进行数据完整性和一致性检查。
- 使用
- 代码示例:
import SwiftUI
import Foundation
struct Person: Identifiable, Codable {
var id: UUID
var name: String
var age: Int
}
struct ContentView: View {
@State private var people: [Person] = [
Person(id: UUID(), name: "Alice", age: 30),
Person(id: UUID(), name: "Bob", age: 25)
]
@State private var droppedPerson: Person? = nil
var body: some View {
VStack {
List(people) { person in
Text(person.name)
.onDrag {
let encoder = JSONEncoder()
if let data = try? encoder.encode(person) {
return NSItemProvider(object: data as NSData)
}
return NSItemProvider()
}
}
.frame(width: 200)
DropZone()
.onDrop(of: [.json], delegate: DropDelegate())
}
}
struct DropZone: View {
var body: some View {
Rectangle()
.fill(Color.gray.opacity(0.2))
.frame(width: 200, height: 200)
.overlay(
Text(droppedPerson == nil? "Drop here" : "Dropped: \(droppedPerson!.name)")
.foregroundColor(.black)
)
}
}
class DropDelegate: NSObject, DropDelegate {
func performDrop(info: DropInfo) -> Bool {
guard let item = info.itemProviders(for: [.json]).first else {
return false
}
item.loadObject(ofClass: NSData.self) { data, error in
guard let data = data as? Data, error == nil else {
return
}
let decoder = JSONDecoder()
if let person = try? decoder.decode(Person.self, from: data) {
// 数据完整性和一致性检查示例:检查年龄是否为正数
if person.age > 0 {
self.droppedPerson = person
} else {
print("Invalid age, data not consistent")
}
}
}
return true
}
}
}
上述代码实现了以下功能:
Person
结构体遵循Identifiable
和Codable
协议。- 在
ListView
中,每个Person
实例可以被拖拽,通过onDrag
将Person
编码为Data
并提供给NSItemProvider
。 DropZone
视图接收拖拽的数据,DropDelegate
中的performDrop
方法负责将接收到的Data
解码回Person
,并进行简单的数据完整性和一致性检查(这里是检查年龄是否为正数)。