英文:
dragging on one TextView drags entire collection in SwiftUI with onDrag modifier
问题
I'll provide the translation of the code you provided, excluding the code comments:
import SwiftUI
struct EmojiArtDocumentView: View {
@ObservedObject var document: EmojiArtDocument
let defaultmojiFontSize: CGFloat = 40
var body: some View {
VStack(spacing: 0) {
documentBody
palette
}
.padding()
}
var documentBody: some View {
GeometryReader { geometry in
ZStack {
Color.yellow
ForEach(document.emojis) { emoji in
Text(emoji.text)
.font(.system(size: fontSize(for: emoji)))
.position(position(for: emoji, in: geometry))
}
}
}
}
private func drop(providers: [NSItemProvider], at location: CGPoint) -> Bool {
false
}
private func fontSize(for emoji: EmojiArt.Emoji) -> CGFloat {
CGFloat(emoji.size)
}
private func position(for emoji: EmojiArt.Emoji, in geometry: GeometryProxy) -> CGPoint {
convertFromEmojiCoordinates((emoji.x, emoji.y), in: geometry)
}
private func convertFromEmojiCoordinates(_ location: (x: Int, y: Int), in geometry: GeometryProxy) -> CGPoint {
let center = geometry.frame(in: .local).center
return CGPoint(
x: center.x + CGFloat(location.x),
y: center.y + CGFloat(location.y)
)
}
var palette: some View {
ScrollingEmojisView(emojis: testemojis)
.font(.system(size: defaultmojiFontSize))
}
let testemojis = "😀🥰😌😇🤓🤩🤪😤👻"
}
struct ScrollingEmojisView: View {
let emojis: String
var body: some View {
ScrollView(.horizontal) {
HStack {
ForEach(emojis.map {String($0) }, id: \.self) { emoji in
Text(emoji)
.onDrag {
NSItemProvider(object: emoji as NSString)
}
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
EmojiArtDocumentView(document: EmojiArtDocument())
}
}
extension CGRect {
var center: CGPoint {
CGPoint(x: midX, y: midY)
}
}
Please note that the code you provided includes some HTML escape sequences (e.g., >
and "
) that need to be decoded when used in Swift. If you encounter issues, make sure to decode these properly in your code.
英文:
I'm trying to work through the EmojiArt app on Stanford 193p 2021, if that reference helps. Otherwise, as the title says, I'm trying to add an onDrag modifier on each of the emoji chars, but it appears as if when I drag on one, the entire string of emoji chars gets dragged. how to fix this?
import SwiftUI
struct EmojiArtDocumentView: View {
@ObservedObject var document: EmojiArtDocument
let defaultmojiFontSize: CGFloat = 40
var body: some View {
VStack(spacing: 0) {
documentBody
palette
}
.padding()
}
var documentBody: some View {
GeometryReader { geometry in
ZStack {
Color.yellow
ForEach(document.emojis) { emoji in
Text(emoji.text)
.font(.system(size: fontSize(for: emoji)))
.position(position(for: emoji, in: geometry))
}
}
}
// .onDrop(of: [.plainText], isTargeted: nil) {
// providers, location in
// return false
// }
}
private func drop(providers: [NSItemProvider], at location: CGPoint) -> Bool {
false
}
private func fontSize(for emoji: EmojiArt.Emoji) -> CGFloat {
CGFloat(emoji.size)
}
private func position(for emoji: EmojiArt.Emoji, in geometry: GeometryProxy) -> CGPoint {
convertFromEmojiCoordinates((emoji.x, emoji.y), in: geometry)
}
private func convertFromEmojiCoordinates(_ location: (x: Int, y: Int), in geometry: GeometryProxy) -> CGPoint {
let center = geometry.frame(in: .local).center
return CGPoint(
x: center.x + CGFloat(location.x),
y: center.y + CGFloat(location.y)
)
}
var palette: some View {
ScrollingEmojisView(emojis: testemojis)
.font(.system(size: defaultmojiFontSize))
}
let testemojis = "😀🥰😌😇🤓🤩🤪😤👻"
}
struct ScrollingEmojisView: View {
let emojis: String
var body: some View {
ScrollView(.horizontal) {
HStack {
ForEach(emojis.map {String($0) }, id: \.self) { emoji in
Text(emoji)
.onDrag {
NSItemProvider(object: emoji as NSString)
}
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
EmojiArtDocumentView(document: EmojiArtDocument())
}
}
extension CGRect {
var center: CGPoint {
CGPoint(x: midX, y: midY)
}
}
答案1
得分: 1
你可以尝试插入 ZStack 并修改 documentBody 属性中的 ForEach,如下所示:
ForEach(document.emojis) { emoji in
ZStack {
Text(emoji.text)
.font(.system(size: fontSize(for: emoji)))
}
.position(position(for: emoji, in: geometry))
.gesture(
DragGesture()
.onChanged { dragValue in
document.moveEmoji(emoji, by: dragValue.translation, in: geometry)
}
)
}
这样,每个 ZStack 将被识别为一个可拖动的单独视图,您将能够拖动单个表情符号字符。
英文:
You can try to insert ZStack and modify ForEach of the documentBody property as below:
ForEach(document.emojis) { emoji in
ZStack {
Text(emoji.text)
.font(.system(size: fontSize(for: emoji)))
}
.position(position(for: emoji, in: geometry))
.gesture(
DragGesture()
.onChanged { dragValue in
document.moveEmoji(emoji, by: dragValue.translation, in: geometry)
}
)
}
This way, each ZStack will be recognized as a separate draggable view, and you will be able to drag individual emoji characters.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论