【问题标题】:Error: UITableView jump to top with UITableViewAutomaticDimension错误:UITableView 使用 UITableViewAutomaticDimension 跳转到顶部
【发布时间】:2016-08-28 08:30:27
【问题描述】:

我将UITableViewestimatedRowHeightUITableViewAutomaticDimension 一起使用。我也使用NSFetchedResultsControllerDelegate 来反映这些变化。

一切正常。现在的问题是,当我向CoreData 添加一些记录时,NSFetchedResultsController 称为它的委托,但发生了意想不到的事情。 TableView 每次都会突然滚动到 Top。

NSFetchedResultsControllerDelegate

func controllerWillChangeContent(controller: NSFetchedResultsController) {
    tableView.beginUpdates()
}

func controllerDidChangeContent(controller: NSFetchedResultsController) {
    tableView.endUpdates()
}

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
        switch type {
        case .Insert:
            tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .None)
            break

        case .Update:
            tableView.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: .None)
            break

        case .Delete:
            tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .None)
            break

        default: break;
        }
    }

通过谷歌搜索,我发现很少有人建议使用 tableView: heightForRowAtIndexPath:answers,但因为我的单元格高度是动态的。所以我该怎么做?

【问题讨论】:

  • 前段时间我已经回答了类似的问题:stackoverflow.com/a/30126655/826716
  • 尝试实现方法, - (void)controllerWillChangeContent:(NSFetchedResultsController *)controller { [self.tableView beginUpdates]; } 和 - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { [self.tableView endUpdates]; }
  • @SanuS 感谢您的建议。它已经在那里了。
  • 您找到解决方案了吗?
  • @guillaume 还没有。 :(

标签: ios swift uitableview core-data uitableviewautomaticdimension


【解决方案1】:

这是 tableview 的默认行为,在 tableview 中插入一行会将其滚动到顶部。 我的应用程序确实遇到了同样的问题。 这是我如何管理tableview的内容偏移量,请按照步骤操作,

1)在插入行或节之前存储UITableview的内容偏移量。

2)在数组中插入对象。

3)重新加载表格视图

4)减去差值,手动设置内容偏移量。

let oldOffset: CGFloat = tblTest.contentSize.height
tblTest.reloadData()
let newOffset: CGFloat = tblTest.contentSize.height
tblTest.setContentOffset(CGPointMake(0, (newOffset - oldOffset)), animated: false)

这就是我迄今为止在我的应用程序中所做的事情,并且使用动态单元格来克服每次重新初始化单元格,它的工作非常棒。

【讨论】:

  • 这对@Tapas pal没有帮助
  • 它部分工作......但不是我想要的方式。重新加载表格视图会丢失插入动画,并且表格视图单元格包含一些视频和图像,因此重新加载表格视图会产生闪烁效果。
  • 不,他们不会,这只是你如何拒绝他们的问题。不要在每次加载时初始化单元格。
  • 我正在将此技术与带有媒体和文本的聊天应用程序一起使用,就像在 whatsapp 中加载更多作品一样工作。
【解决方案2】:
func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    tabelView.reloadData()
}

这对我有用

【讨论】:

    【解决方案3】:
    let cou : Int = self.Array.count as Int
    let lastindex : NSIndexPath = NSIndexPath(forRow: cou-1, inSection: 0)
    self.TableName.scrollToRowAtIndexPath(lastindex, atScrollPosition: UITableViewScrollPosition.None, animated: true)
    

    此代码可帮助您在特定位置滚动表格视图。

    【讨论】:

      【解决方案4】:

      为了解决我的问题,我将单元格高度保存在 willDisplay 方法中,并在 estimatedHeightForRowAt 中检索值。

      var cellHeights = NSMutableDictionary()
      
      override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
          return UITableViewAutomaticDimension
      }
      
      override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
          if let height = cellHeights.object(forKey: indexPath) {
              return height as! CGFloat
          }
      
          return UITableViewAutomaticDimension
      }
      
      override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
          cellHeights.setObject(cell.frame.size.height, forKey: indexPath as NSCopying)
      }
      

      【讨论】:

      • 虽然我没试过但怀疑它能否解决跳跃问题。
      • 很好的答案!在潜伏 3 天后帮助了我
      【解决方案5】:
        func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
          switch type {
          case .Insert:
      
            tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .None)
              break
      
          case .Update:
              tableView.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: .None)
              break
      
          case .Delete:
              tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .None)
              break
      
          default: break;
          }
         tableView.reloadData()
        let indexPath = NSIndexPath(forRow: 0, inSection: 0)
        self. tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Top, animated: true)
         }
      
      }
      

      【讨论】:

      • 如果我调用 reloadData() 方法,它会删除所有动画对吗?
      • 另外,当您将滚动位置设置为 indexPath 时,这意味着它将始终尝试聚焦在最底部的单元格。
      • 你为什么不添加一些解释?您的答案质量极低
      【解决方案6】:

      添加到@jayesh-miruliya 的答案,在你的NSFetchedResultsControllerDelegate switch 语句之后,把它放在你的代码中:

      tableView.reloadData()
      dispatch_async(dispatch_get_main_queue(), {
          let topCellIndexPath = NSIndexPath(forRow: 0, inSection: 0)
          self. tableView.scrollToRowAtIndexPath(topCellIndexPath, atScrollPosition: .Top, animated: true)
      })
      

      【讨论】:

      • 是的,我有,你应该把UI相关的代码放在Main Queue中,并使用animated: true,而不是突然到顶部,它会动画它。您也可以在 atScrollPosition 中使用“.Bottom”。
      • 你为什么不添加一些解释?您的答案质量极低
      • 我认为发生了一些误解。我的意图不是将表格视图滚动到顶部或底部。插入新单元格时,表格视图不应自动向上或向下滚动。
      • @TapasPal 我在我的项目中做了类似的事情,并且 deleteAtIndexPaths 可以在不滚动 tableView 的情况下正常工作。 tableView在scrollsToTop的时候,清空表格,重新插入数据?您是否在代码中的其他任何地方重新加载表格?我认为其他一些方法/回调导致了这个问题。
      【解决方案7】:
      tableView.reloadData()
      if tableView.numberOfRowsInSection(0) > 0
      {
            let indexPath = NSIndexPath(forRow: 0, inSection: 0)
            self. tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Top, animated: true)
      }
      

      【讨论】:

      • 我应该在哪里添加这个?
      • 你为什么不添加一些解释?您的答案质量极低
      • 我认为发生了一些误解。我的意图不是将表格视图滚动到顶部或底部。插入新单元格时,表格视图不应自动向上或向下滚动。
      • 我仍然不明白您为什么不对您的答案做出解释。只是发布代码的答案质量极低
      猜你喜欢
      • 2019-01-03
      • 2013-02-22
      • 1970-01-01
      • 2016-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多