как мне сделать модификатор просмотра swiftui, который принимает любой объект?

В моих проектах есть довольно много многоразовых модификаторов просмотра, но мне никогда не удавалось создать такой, который принимает какой-либо объект вместо конкретного объекта.

Fx. в приведенном ниже модификаторе представления, как я могу заставить его принимать любой объект вместо «StopContent», чтобы мне не приходилось писать новый viewModifier каждый раз, когда я хотел использовать его для нового объекта?

      struct DragToDeleteContent: ViewModifier {
    
    let stopContent:StopContent
    @Binding var contentArray: [StopContent]
    @State private var deleted:Bool = false
    
    func body(content: Content) -> some View {
        return content
            .dragToDelete(deleted: $deleted)
            .onChange(of: deleted, perform: { deleted in
                if deleted { delete() }
            })
    }
    
    func delete() {
        if let arrayIndex = contentArray.firstIndex(of: stopContent) {
            contentArray.remove(at: arrayIndex)
        }
    }
}

1 ответ

Решение

Каждая модель подтверждается Identifiable протокол, чтобы вы могли сделать его универсальным с помощью Identifiable.

вот возможное решение

      struct DragToDeleteContent<T: Identifiable>: ViewModifier {
    
    let stopContent: T
    @Binding var contentArray: [T]
    @State private var deleted:Bool = false
    
    func body(content: Content) -> some View {
        return content
            .dragToDelete(deleted: $deleted)
            .onChange(of: deleted, perform: { deleted in
                if deleted { delete() }
            })
    }
    
    func delete() {
        if let arrayIndex = contentArray.firstIndex(where: {$0.id == stopContent.id}) {
            contentArray.remove(at: arrayIndex)
        }
    }
}

Модель данных

      struct TestModel: Identifiable {
    var id = UUID()
    var name: String
}

Применение

      }.modifier(DragToDeleteContent(stopContent: TestModel(name: "Abc"), contentArray: .constant([.init(name: "Xyz"), .init(name: "opq")]))) // I used .constant for the demo purpose. Bind you Identifiable array here.
Другие вопросы по тегам