SwiftUI onDrop не работает с DropDelegate на iOS18IOS

Программируем под IOS
Ответить Пред. темаСлед. тема
Anonymous
 SwiftUI onDrop не работает с DropDelegate на iOS18

Сообщение Anonymous »

Я новичок в SwiftUI, и я написал структуру ReorderableForEach с onDrag и onDrop, которая хорошо работает на iOS17.
Однако она не работает на iOS18 beta1 или beta2 на моем iPhone или симуляторе. При длительном нажатии на элемент ничего не происходит.
Когда я удаляю onDrop, я могу выполнить анимацию перетаскивания, поэтому я думаю, что что-то не так с моим кодом onDrop.
весь код:

Код: Выделить всё

import UIKit
import SwiftUI

public typealias Reorderable = Identifiable & Equatable

struct GridData: Identifiable, Equatable {
let id: Int
}

public struct ReorderableForEach: View {
@Binding
private var active: Item?

@State
private var hasChangedLocation = false

private let items: [Item]
private let content: (Item) -> Content
private let preview: ((Item) -> Preview)?
private let moveAction: (IndexSet, Int) -> Void
private var onDropAction: ((Item) -> Void)?
private var allowReorder: Bool

public init(
_ items: [Item],
active: Binding,
allowReorder: Bool,
@ViewBuilder content: @escaping (Item) -> Content,
@ViewBuilder preview: @escaping (Item) -> Preview,
moveAction: @escaping (IndexSet, Int) -> Void,
onDropAction: ((Item) -> Void)? = nil
) {
self.items = items
self._active = active
self.allowReorder = allowReorder
self.content = content
self.preview = preview
self.moveAction = moveAction
self.onDropAction = onDropAction
}

public init(
_ items: [Item],
active: Binding,
allowReorder: Bool,
@ViewBuilder content: @escaping (Item) -> Content,
moveAction: @escaping (IndexSet, Int) -> Void,
onDropAction: ((Item) -> Void)? = nil
) where Preview == EmptyView {
self.items = items
self._active = active
self.allowReorder = allowReorder
self.content = content
self.preview = nil
self.moveAction = moveAction
self.onDropAction = onDropAction
}

public var body: some View {
ForEach(items) { item in
if !allowReorder {
contentView(for: item)
}
else if let preview {
contentView(for: item)
.onDrag {
return dragData(for: item)
} preview: {
preview(item)
}
} else {
contentView(for: item)
.onDrag {
return dragData(for: item)
}
}
}
}

private func contentView(for item: Item) -> some View {
content(item)
.opacity(active == item && hasChangedLocation ? 0.5 : 1)
.onDrop(
of: [.text],
delegate: ReorderableDragRelocateDelegate(
item: item,
items: items,
active: $active,
hasChangedLocation: $hasChangedLocation
) { from, to in
withAnimation {
moveAction(from, to)
}
} onDropAction: { item in
onDropAction?(item)
}
)
}

private func dragData(for item: Item) -> NSItemProvider {
active = item
return NSItemProvider(object: "\(item.id)" as NSString)
}
}

struct ReorderableDragRelocateDelegate: DropDelegate {
let item: Item
var items: [Item]

@Binding var active: Item?
@Binding var hasChangedLocation: Bool

var moveAction: (IndexSet, Int) -> Void
var onDropAction: ((Item) -> Void)?

func dropEntered(info: DropInfo) {
guard item != active, let current = active else { return }
guard let from = items.firstIndex(of: current) else { return }
guard let to = items.firstIndex(of: item) else { return }

hasChangedLocation = true

if items[to] != current {
moveAction(IndexSet(integer: from), to > from ? to + 1 : to)

}
}

func dropUpdated(info: DropInfo) ->  DropProposal? {
DropProposal(operation: .move)
}

func performDrop(info: DropInfo) -> Bool {
hasChangedLocation = false
active = nil
onDropAction?(item)
return true
}
}

struct ReorderableDropOutsideDelegate: DropDelegate {

@Binding
var active: Item?

func dropUpdated(info: DropInfo) -> DropProposal? {
DropProposal(operation: .move)
}

func performDrop(info: DropInfo) -> Bool {
active = nil
return true
}
}

public extension View {
func reorderableForEachContainer(
active: Binding
) -> some View {
onDrop(of: [.text], delegate: ReorderableDropOutsideDelegate(active: active))
}
}

#Preview {
ReorderableForEach(
(1...10).map { GridData(id: $0) },
active: .constant(nil),
allowReorder: true
) { item in
Text("Item \(item.id)")
.padding()
.background(Color.blue)
.cornerRadius(8)
} preview: { item in
Text("Preview \(item.id)")
.padding()
.background(Color.red)
.cornerRadius(8)
} moveAction: { from, to in
print("Move from \(from) to \(to)")
}
}
Я что-то упустил или это ошибка iOS18?

Заранее спасибо.


Подробнее здесь: https://stackoverflow.com/questions/786 ... e-on-ios18
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Сбой ios18.0.1 не произошел в ios18.1? [закрыто]
    Anonymous » » в форуме IOS
    0 Ответы
    13 Просмотры
    Последнее сообщение Anonymous
  • `View.ondrag (_ :)` вызывается снова после `dropdelegate.performdrop (info :)`
    Anonymous » » в форуме IOS
    0 Ответы
    11 Просмотры
    Последнее сообщение Anonymous
  • Почему в обработчике события onDrop React Big Calendar в реквизите «event» отсутствует тип «id» (с использованием Typesc
    Гость » » в форуме Javascript
    0 Ответы
    49 Просмотры
    Последнее сообщение Гость
  • Event.dataTransfer.files пуст при запуске ondrop?
    Anonymous » » в форуме Html
    0 Ответы
    30 Просмотры
    Последнее сообщение Anonymous
  • Как изменить цвет фона приложения в MAUI для iOS18
    Anonymous » » в форуме C#
    0 Ответы
    10 Просмотры
    Последнее сообщение Anonymous

Вернуться в «IOS»