es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo actualizar el indexPath de la celda de la lista de vista de colección cuando se agrega o elimina la celda?

Estoy trabajando en la celda de lista de vista de colección y me preguntaba cómo actualizar el indexPath cuando uso la fuente de datos diferenciable y el snapshot en iOS14.

En el viewdidload de mi ViewController, llamé al método configureDataSource que registra la información de la celda. Además, tengo un método displayEvents que recupera los datos de eventos del backend y los muestra en la celda de la vista de colección. El eventDataSource tiene una matriz de eventos, por lo que cuando se recuperan los datos de eventos, actualiza la matriz para que la ViewController pueda mostrar los datos.

También tengo una función addEvent que se llama desde EventActionModalViewController, como si un usuario escribiera el nombre del evento y enviara la solicitud API .save para almacenar los datos en la base de datos. Funciona bien, es decir, agrega correctamente los datos al backend y muestra el nuevo evento en la lista de vista de colección. Sin embargo, el problema es que el indexPath de la vista de colección no se actualiza.

Por ejemplo, si ya hay dos eventos en la vista de colección, su indexPath es [0,0] y [0,1]. (Los imprimí en “aquí está el indexPath: (indexPath)”). Y después de agregar el nuevo evento, hay tres eventos en la vista de colección, lo cual es correcto, pero el indexPath se convierte en [0,0], [0,0] y [0,1]. Entonces creo que el indexPath de los eventos que ya se muestran no se actualiza. ¿Aplicar un snapshot no es suficiente para actualizar el indexPath de cada celda? Pensé que incluso después de aplicar el snapshot, aún necesita actualizar la vista de colección para aplicar un nuevo indexPath a la celda, o algo similar.

¿Alguien ha enfrentado el mismo problema? Si es así, ¿cómo aplicó el nuevo indexPath a la celda? También tengo una función para eliminar la celda, pero tampoco actualiza el indexPath. Por cierto, estoy trabajando en la aplicación para iOS14, así que no puedo usar una para iOS15…

“`Swift
private var eventDataSource = EventDataSource()

override func viewDidLoad() {
super.viewDidLoad()

<pre><code>setupCollectionView() // -> crea la vista de colección y establece restricciones
configureDataSource()
displayEvents()
</code></pre>

}

func configureDataSource() {

<pre><code>let cellRegistration = UICollectionView.CellRegistration<listcell, event=""> { cell, indexPath, Event in

cell.Event = Event

let moreAction = UIAction(image: Images.setting) { _ in
let vc = EventActionModalViewController();
vc.modalPresentationStyle = .overCurrentContext
print("aquí está el indexPath: \(indexPath)")
vc.indexPath = indexPath
self.tabBarController?.present(vc, animated: false, completion: nil)
}

let moreActionButton = UIButton(primaryAction: moreAction)
moreActionButton.tintColor = UIColor.ouchienLightGray()
let moreActionAccessory = UICellAccessory.CustomViewConfiguration(
customView: moreActionButton,
placement: .trailing(displayed: .whenEditing, at: { _ in return 0 })
)

cell.accessories = [
.customView(configuration: moreActionAccessory),
.disclosureIndicator(displayed: .whenNotEditing, options: .init(tintColor: .systemGray))
]
}

dataSource = UICollectionViewDiffableDataSource<section, event="">(collectionView: collectionView) {
(collectionView, indexPath, Event) -> UICollectionViewCell? in
let cell = collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: Event)
return cell
}
</code></pre>

}

func displayEvents() {
eventDataSource.fetchEvents { [weak self] in
self?.applySnapshot(animatingDifferences: true)
}
}

func addEvent(EventTitle: String) {
eventDataSource.save(eventTitle: EventTitle, completion: { [weak self] in
self?.applySnapshot(animatingDifferences: true)
})
}

func applySnapshot(animatingDifferences: Bool = true) {

<pre><code>snapshot = NSDiffableDataSourceSnapshot<section, event="">()
snapshot.appendSections([.List])
snapshot.appendItems(eventDataSource.Events)
dataSource?.apply(snapshot, animatingDifferences: animatingDifferences)
</code></pre>

}
“`</section,></section,></listcell,>

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Parece ser que el indexPath de tu colección de vistas no se actualiza después de agregar o eliminar un evento usando el origen de datos y instantánea diferenciable. Para actualizar el indexPath, se puede intentar usar el método reloadItems de la colección de vistas para recargar los elementos cambiados.

    Después de aplicar la instantánea, se puede recargar el elemento cambiado usando su indexPath. Por ejemplo, en la función addEvent, después de applySnapshot(animatingDifferences: true), se puede agregar el siguiente código:

    if let addedEventIndex = eventDataSource.Events.firstIndex(where: { $0.title == EventTitle }) {
        let indexPath = IndexPath(item: addedEventIndex, section: 0)
        collectionView.reloadItems(at: [indexPath])
    }
    

    Esto debe recargar la celda del evento recién agregado y actualizar su indexPath en la colección de vistas.

    De manera similar, se puede usar el método deleteItems y luego recargar los elementos restantes para actualizar sus indexPaths después de eliminar un evento.

    ¡Espero que esto ayude!

Comments are closed.