2016-03-07 3 views
1

У меня есть ячейка, у которой есть изображение в ней, которое извлекается из Amazon S3. Высота этого изображения влияет на высоту ячейки, но, к сожалению, изображение извлекается в обработчике завершения после определения высоты ячейки. Если я прокручу вниз и вверх, ячейка перезагрузится должным образом.Высота ячейки не вычисляется должным образом из-за обработчика завершения

Перед прокрутки (неправильный рост клеток): enter image description here

После прокрутки (правильная высоты ячейки): enter image description here

конфигурации клеток (некоторые ненужные вещи отредактированных для удобства чтения):

func setCompletionCell(completion: CompletionPublic, contentType: String, classType: String){ 
     self.completionPub = completion 
     self.selectionStyle = UITableViewCellSelectionStyle.None //Disables clicking 

     //Setting image or video 
     if (contentType == "image"){ 
      nwa.fetchSignedUrl("image/accepted/" + completion.mediaId + ".png") { (result, err) in 
       self.nwa.fetchImage(result) { (image, err) in 

        if image != nil{ 
         let screenSize: CGRect = UIScreen.mainScreen().bounds 

         var multiplyNum = screenSize.width/image.size.width 
         //if image height is going to be more than 60% of the screen, resize width and height to ensure that it isn't greater than 60% while keeping the aspect ratio correct 
         if ((image.size.height*multiplyNum) > (screenSize.height*0.6)){ 
          multiplyNum = screenSize.height*0.6/image.size.height 
          self.imageViewWidthConstraint.constant = (multiplyNum*image.size.width) 
          self.imageViewHeightConstraint.constant = screenSize.height*0.6 
         } 
         else{ 
          self.imageViewWidthConstraint.constant = screenSize.width 
          self.imageViewHeightConstraint.constant = (multiplyNum*image.size.height) 
         } 
         self.imgView.image = image 

        } 
        else{ 
         //no image returned 
        } 


       } 
      } 
     } 
     else if (contentType == "video"){ 
      ytplayer.loadWithVideoId(completion.mediaId) 
     } 


    } 

Методы делегирования TableView:

func callNWT(tableView: UITableView, completionHandler:() ->()) { 
    switch trendingToggle { 
    case 0: 
     nwt.getTrendingBounties(0) { (bountyArr, err) in 
      //@TODO: change pos 
      if bountyArr == nil { 
       self.bountyArr = [] 
      } 
      else { 
       self.bountyArr = bountyArr as [BountyPublic] 
      } 

      if self.bountyArr.count == 0 { 
       completionHandler() 
      } 
      self.reloadTableViewContent(tableView) 
     } 
    case 1: 
     nwt.getTrendingCompletions(0) { (compArr, err) in 
      if compArr == nil { 
       self.compArr = [] 
      } 
      else { 
       self.compArr = compArr as [CompletionPublic] 
      } 
      if self.compArr.count == 0 { 
       completionHandler() 
      } 
      self.reloadTableViewContent(tableView) 
     } 
    case 2: 
     nwt.getTrendingPeople(0) { (peopleArr, err) in 
      if peopleArr == nil { 
       self.peopleArr = [] 
      } 
      else { 
       self.peopleArr = peopleArr as [Person] 
      } 

      if self.peopleArr.count == 0 { 
       completionHandler() 
      } 
      self.reloadTableViewContent(tableView) 
     } 
    default: 
     break 
    } 
} 

func configureTableView(tableView: UITableView){ 
    tableView.rowHeight = UITableViewAutomaticDimension 
    tableView.estimatedRowHeight = 500.0 
    tableView.allowsSelection = false; //disables selection highlighting of cells 
    tableView.tableFooterView = UIView() 
    tableView.dataSource = self 
} 

func reloadTableViewContent(tableView: UITableView) { 
    dispatch_async(dispatch_get_main_queue(), {() -> Void in 
     tableView.reloadData() 
     print("reloading table view content") 
     tableView.scrollRectToVisible(CGRectMake(0, 0, 1, 1), animated: false) 
    }) 
} 


func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    if trendingToggle == 0 { 
     return bountyArr.count 
    } 
    else if trendingToggle == 1 { 
     return compArr.count 
    } 
    else { 
     return peopleArr.count 
    } 
} 


func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    if trendingToggle == 0 { 
     return bountyCellAtIndexPath(tableView, indexPath: indexPath) 
    } 
    else if trendingToggle == 1 { 
     return completedCellAtIndexPath(tableView, indexPath:indexPath) 
    } 
    else { 
     return personCellAtIndexPath(tableView, indexPath: indexPath) 
    } 
} 

func completedCellAtIndexPath(tableView: UITableView, indexPath:NSIndexPath) -> CompletedCell{ 
    var cell: CompletedCell 
    if compArr[indexPath.row].contentType == "image" { 
     cell = tableView.dequeueReusableCellWithIdentifier(completedImgCellIdentifier) as! CompletedCell 
     let comp = compArr[indexPath.row] 
     cell.setCompletionCell(comp, contentType: "image", classType: "trending") 
    } 
    else { //video 
     cell = tableView.dequeueReusableCellWithIdentifier(completedVidCellIdentifier) as! CompletedCell 
     let comp = compArr[indexPath.row] 
     cell.setCompletionCell(comp, contentType: "video", classType: "trending") 
    } 
    return cell 
} 

Как обеспечить правильное вычисление высоты ячейки в первый раз? Есть ли способ задержать выполнение кода до получения изображения? Или это не очень хорошая идея?

+1

опубликуйте некоторый код, методы делегата в виде таблицы и конфигурацию ячейки. – Lucho

+0

Вы не должны останавливать основную очередь для сетевых запросов. Что вам нужно сделать, так это после установки изображения, которое вы должны уведомить о представлении таблицы в макеты. –

+0

Код для примера здесь http://stackoverflow.com/questions/33975355/updating-cell-height-after-image-downloads – AdamM

ответ

1

Обновить табличное представление в обработчике завершения.

tableView.reloadData()

В методе heightForRowAtIndex для протоколов DataSource/делегата пересчитать высоту, используя изображение и возвращает соответствующее значение для каждой отдельной клетки.

Когда вы вызываете reloadData(), все методы datasource/delegate вызываются снова, поэтому возвращаемая правильная высота позволит вам изменить размер ячейки по мере необходимости.

+0

Перезагрузка tableview не работает, если изображения не сохранены и не восстановлены. Кроме того, вы можете просто перезагрузить эту ячейку, а не перезагружать всю таблицу снова и снова. – Nishant

+0

вы правы всей таблицыView не нужно перезагружать - просто рассматриваемая строка, но почему изображение нужно сохранять локально? (Я предполагаю, что вы имеете в виду в комплекте приложений). Почему вы не можете получить изображение с сервера, чтобы сохранить его в массиве в делетете источника данных, и вызвать (какой бы тобой) reloadTableView, который вам нравится, а затем в методе heightForRowAtIndex вернуть высоту изображения, соответствующего indexPath.row, в массив изображений? –

+0

Решено, сохраняя локально, а затем вызывая tableView.reloadData() и не получая изображение с S3 снова. Спасибо @ Нишант и Блейк. – Mitchell

Смежные вопросы