2017-01-28 1 views
2

Ive искал ответ на этот вопрос в течение нескольких дней и не мог понять, как это сделать. У меня есть Collection View с пользовательской ячейкой. Когда вы дважды коснитесь ячейки в коллекции, она либо загрузит файл, либо удалит его, если он был загружен ранее.CollectionView Cell и Progress Bar - индикатор выполнения в неправильной ячейке после прокрутки

Во время загрузки индикатор выполнения отображает ход загрузки, а затем отображает небольшую иконку в верхнем левом углу. При удалении удаляет значок.

enter image description here

Если вы загружаете из одной ячейки и удалить из другого, а первая загрузка в процессе он работает нормально, но только тогда, когда обе клетки были видны в представлении коллекции.

enter image description here

если я загрузить из одной ячейки, а затем прокрутить закадровый и удалить из клетки, которая не находится в том же экране, как ячейки, находящегося загрузка с, она снимает угол изображения, как обычно, а затем отображает ход bar ячейки, которая загружается из.

enter image description here

Я не знаю, если это ошибка с тем, как я повторно использовать клетки ??? Кажется, что это не имеет никакого отношения к тому, как я обновляю представление ячейки или коллекции, которое работает во всех случаях, кроме как после прокрутки.

Ниже 2 функции, которые скачивают или удалить файл:

func downloadDataToDevice(cell: JourneyCollectionViewCell, selectedIndexPath: IndexPath){ 

    let downloadedAudio = PFObject(className: "downloadedAudio") 
    // save all files with unique name/object id 
    let selectedObjectId = self.partArray[selectedIndexPath.item].id 
    let selectedPartName = self.partArray[selectedIndexPath.item].name 

    let query = PFQuery(className: "Part") 
    query.whereKey("objectId", equalTo: selectedObjectId) 
    query.getFirstObjectInBackground { (object, error) in 

     if error != nil || object == nil { 
      print("No object for the index selected.") 
     } else { 
      //print("there is an object, getting the file.") 
      downloadedAudio.add(object?.object(forKey: "partAudio") as! PFFile, forKey: selectedPartName) 
      let downloadedFile = object?.object(forKey: "partAudio") as! PFFile 

      // get the data first so we can track progress 
      downloadedFile.getDataInBackground({ (success, error) in 
       if (success != nil) { 
        // pin the audio if there is data 
        downloadedAudio.pinInBackground(block: { (success, error) in 
         if success { 

          // reload the cell 
          self.reloadCell(selectedIndexPath: selectedIndexPath, hideProgress: true, hideImage: false, cell: cell) 
          self.inProgress -= 1 
          cell.isUserInteractionEnabled = true 

         } 
        }) 
       } 
      // track the progress of the data 
      }, progressBlock: { (percent) in 
       self.activityIndicatorView.stopAnimating() 
       cell.progessBar.isHidden = false 
       //cell.progessBar.transform = cell.progessBar.transform.scaledBy(x: 1, y: 1.1) 
       cell.contentView.bringSubview(toFront: cell.progessBar) 
       cell.progessBar.setProgress(Float(percent)/Float(100), animated: true) 
       cell.isUserInteractionEnabled = false 
      }) 
     } 
    } 
} 

func removeDataFromDevice(cell: JourneyCollectionViewCell, selectedIndexPath: IndexPath, object: PFObject) { 

     let selectedPartName = self.partArray[selectedIndexPath.item].name 

     // unpin the object from the LocalDataStore 
     PFObject.unpinAll(inBackground: [object], block: { (success, error) in 
      if success { 
       // reduce inProgress 
       self.inProgress -= 1 
       self.reloadCell(selectedIndexPath: selectedIndexPath, hideProgress: true, hideImage: true, cell: cell) 
      } 
     }) 
} 

и это, как я перегрузочные клетки

func reloadCell(selectedIndexPath: IndexPath, hideProgress: Bool, hideImage: Bool, cell: JourneyCollectionViewCell) { 
    cell.progessBar.isHidden = hideProgress 
    cell.imageDownloaded.isHidden = hideImage 
    self.collectionView.reloadItems(at: [selectedIndexPath]) 
} 

----------- EDIT -------------

Это мой cellForItem при работе. В настоящее время я использую запрос для поиска на локальном диске и вижу, существует ли файл, а затем добавляет угловое изображение, если оно есть. Это первый раз, когда я использовал запрос в этом месте, обычно это запрос при входе в систему для заполнения массива, но для более статического сбора данных, чем я пытаюсь достичь здесь, позволяя пользователю загружать и удалять файлы.

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 

    let cell: JourneyCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! JourneyCollectionViewCell 

     cell.imageCell.file = self.partArray[indexPath.item].image 
     cell.imageCell.loadInBackground() 
     cell.imageCell.layer.masksToBounds = true 

    // not sure if its good to run a query here as its constantly updated. 
    // query if file is on LDS and add image to indicate 
    let cellPartName = self.partArray[indexPath.item].name 
    let checkQuery = PFQuery(className: "downloadedAudio") 
     checkQuery.whereKeyExists(cellPartName) 
     checkQuery.fromLocalDatastore() 
     checkQuery.getFirstObjectInBackground(block: { (object, error) in 
     if error != nil || object == nil { 
      //print("The file does not exist locally on the device, remove the image.") 
      cell.imageDownloaded.isHidden = true 
      cell.imageDownloaded.image = UIImage(named: "") 
      cell.progessBar.isHidden = true 

     } else { 
      //print("the file already exists on the device, add the image.") 
      cell.contentView.bringSubview(toFront: cell.imageDownloaded) 
      cell.imageDownloaded.isHidden = false 
      cell.imageDownloaded.image = UIImage(named: "download-1") 

      } 
     }) 
    return cell 
} 

ответ

1

Итак, я попытался проследить прогресс прогресса программно, я попробовал prepareForReuse в пользовательском классе ячеек, не решил эту проблему напрямую, хотя я буду продолжать использовать prepareForReuse, поскольку я считаю, что это более чистый способ управлять ячейкой, чем я был.

Что, похоже, работал было перемещение клетки в progressBlock

if let downloadingCell = self.collectionView.cellForItem(at: selectedIndexPath) as? JourneyCollectionViewCell {       downloadingCell.progessBar.isHidden = false 
    downloadingCell.contentView.bringSubview(toFront: downloadingCell.progessBar) 
    downloadingCell.progessBar.setProgress(Float(percent)/Float(100), animated: true) 
    downloadingCell.setNeedsDisplay() 
    downloadingCell.isUserInteractionEnabled = false 
} 

enter image description here

3

Это нормальная функция ячеек «повторного использования» для эффективного управления памятью. Что вам нужно сделать, это сбросить значение ячеек в поле ниже функции:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
} 

сброс, я имею в виду набора клеток в состояние по умолчанию, перед вами делать какое-либо обновление, такие как добавление значка левого угла или статуса бар.

Вам необходимо убедиться, что массивы, которые вы кормите данными сбора, поддерживаются должным образом. Например, если у вас есть массив A = [1,2,3], и вы удалите A [1], тогда массив A должен быть [1,3].

+0

Я немного не уверен, что вы имеете в виду именно, путем сброса клеток в состояние по умолчанию перед добавлением каких-либо дополнительных элементов пользовательского интерфейса , Я привязал свою функцию cellForItemAt к исходному вопросу ... Итак, что же он делает, используя массив, созданный при входе в систему, чтобы заполнить основное изображение (зеленый 1 - 2 ect) и некоторые другие данные, используемые в другом месте. Затем (и это единственное место, где я сделал это раньше), его запрос локального устройства для имени файла (который из вышеупомянутого массива), чтобы узнать, существует ли он ... – Pippo

+0

Функции в основном вопросе (downloadDataToDevice и removeDataFromDevice) либо добавьте, либо удалите эти данные из локального устройства и таблицы локальных данных, поэтому я думаю, что это обрабатывает часть обслуживания, о которой вы упомянули. Я полагаю, что добавление элементов ui программно только к требуемой ячейке, когда это необходимо, может быть более точным подходом. – Pippo