Swift ios 9: позиция изменения заголовка раздела после данных перезагрузки

У меня есть простой UITableView со многими разделами и строками. Разделы работают нормально. Но иногда после перезагрузки данных таблицы позиция изменения раздела. Например, это произошло, когда я меняю вкладки. В чем может быть проблема?

Изображение перед измененными вкладками:

Before change tab

Изображение после измененных вкладок:

After change tab

Update: Добавить код ниже:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)

    self.dishesListTableView.reloadData()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}


func customizeCollectionView() {
    self.collectionView.delegate = self
    self.collectionView.dataSource = self
    self.collectionView.dataProviderDelegate = self.dishesListDataProvider
    self.collectionView.showsHorizontalScrollIndicator = false
    self.collectionView.decelerationRate = UIScrollViewDecelerationRateFast
    self.collectionView.registerClass(HPCollectionViewCell.self, forCellWithReuseIdentifier: HPCollectionViewCellConstants.reuseIdentifier)
}

//MARK: - UITableViewDelegate
func customziseDishesListTableView(){
    self.dishesListTableView.delegate = self
    self.dishesListTableView.dataSource = self

    self.dishesListTableView.registerNib(UINib(nibName: DishesListSingleTableViewCell.nibName, bundle: nil), forCellReuseIdentifier: DishesListSingleTableViewCell.nibName)
    self.dishesListTableView.registerNib(UINib(nibName: DishesListSinglePizzaTableViewCell.nibName, bundle: nil), forCellReuseIdentifier: DishesListSinglePizzaTableViewCell.nibName)

    self.dishesListTableView.estimatedRowHeight = 123
    self.dishesListTableView.rowHeight = UITableViewAutomaticDimension

    if self.dishesListDataProvider.isPizza() {
        self.dishesListTableView.separatorColor = UIColor.clearColor()
    }else{
        self.dishesListTableView.separatorColor = UIColor.expSilverColor()
    }
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.dishesListDataProvider.countOfDishes(section)
}

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return self.dishesListDataProvider.countOfKitchenTypes()
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    if self.dishesListDataProvider.getDishItemByIndex(indexPath.section, indexDish: indexPath.row).isPizza() {
        let cell = tableView.dequeueReusableCellWithIdentifier(DishesListSinglePizzaTableViewCell.nibName, forIndexPath: indexPath) as! DishesListSinglePizzaTableViewCell
        cell.customizeView(self.dishesListDataProvider.getDishItemByIndex(indexPath.section, indexDish: indexPath.row), dishesListSingleTableViewCellProtocol: self, indexPath: indexPath)
        return cell
    }else{
        let cell = tableView.dequeueReusableCellWithIdentifier(DishesListSingleTableViewCell.nibName, forIndexPath: indexPath) as! DishesListSingleTableViewCell

        cell.customizeView(self.dishesListDataProvider.getDishItemByIndex(indexPath.section, indexDish: indexPath.row), dishesListSingleTableViewCellProtocol: self, indexPath: indexPath)
        return cell
    }
}

func tableView(tableView: UITableView, willDisplayFooterView view: UIView, forSection section: Int) {
    self.collectionView.scrollToIndex(section, animated: true)
    self.collectionView.changeSelectionForCellAtIndexPath(NSIndexPath(forItem: section, inSection: 0))
}

func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let sectionView = NSBundle.mainBundle().loadNibNamed(DishesListSectionView.nibName, owner: self, options: nil)[0] as! DishesListSectionView

    sectionView.customizeView(self.dishesListDataProvider.getKitchenItemByIndex(section).kitchenTypeTitle)

    return sectionView
}
//MARK: - UIScrollViewDelegate
func scrollViewDidScroll(scrollView: UIScrollView) {
    if currentSectionIndex != self.dishesListTableView.indexPathsForVisibleRows![0].section {
        currentSectionIndex = self.dishesListTableView.indexPathsForVisibleRows![0].section
        self.collectionView.scrollToIndex(currentSectionIndex, animated: true)
        self.collectionView.changeSelectionForCellAtIndexPath(NSIndexPath(forItem: currentSectionIndex, inSection: 0))
    }

}

Ответ 1

Я знаю, что это старый поток, но снимите флажок Adjust Scroll View Insets не помогает. У меня была эта проблема, и я решил ее дважды перезагрузить таблицу.

Ответ 2

tableView.reloadData()
tableView.layoutIfNeeded()
tableView.beginUpdates()
tableView.endUpdates()

Это поможет мне.

Двойной reloadData вызовет мерцание, пока этого решения не будет.

Ответ 3

Вызов reloadData() дважды работает для меня, но я бы предложил вызвать tableView.layoutSubviews() после reloadData(), который также работает для меня.

Ответ 4

Похоже, проблема в оценочной высоте для ваших ячеек таблицы. Из-за внутренней оптимизации система вычисляет высоту отсутствующих ячеек на основе оцененного значения высоты, поэтому она может позиционировать ваши заголовки на неправильной расчетной высоте (например, реальные ячейки больше или меньше их расчетного размера). Обычно это происходит, когда вы вызываете reloadData() в середине списка. В качестве правильного решения вам следует избегать вызова reloadData(), если вы хотите, например, обновить содержимое списка со второй страницей. Поэтому вы должны использовать tableView.beginUpdates() и tableView.endUpdates() и обновить коллекцию элементов для представления таблицы. Существует также новый API на основе закрытия performBatchUpdates (как и для UICollectionView), но он доступен из iOS 11.

Надеюсь, что это поможет найти подходящее решение для вас.

Ответ 5

Это из-за свойства UI viewcontroller. Сначала выберите UIViewController From Storyboard, Attribute Inspector

введите описание изображения здесь

Ответ 6

В моем проекте эта ошибка произошла, когда я вытягиваю tableView, чтобы запросить больше данных, а затем перезагрузите данные после запроса. Мне нужно создать много разделов после запроса данных, и это может повлиять на производительность, если я reloadData дважды. Более того, я обнаружил, что если я прокручиваю вверх или вниз по tableView, позиция раздела headerView становится правильной. Поэтому я исправляю эту ошибку (мое условие), запрашивая данные:

[_tableView reloadData];
CGPoint offSetOrigin     = _tableView.contentOffset;
CGPoint offSetSecond     = CGPointMake(0, offSet.y-1);
_tableView.contentOffset = offSetSecond;
_tableView.contentOffset = offSet;

Ответ 7

Решения здесь не помогли решить мою проблему, поэтому я оставляю еще одно возможное решение, которое помогло мне.

Установите estimatedSectionHeaderHeight, похоже, что мой tableView не смог вычислить начальную позицию моего первого раздела без него.

Ответ 8

timateRowHeight вызывает эту проблему.

Обратитесь к этому ответу fooobar.com/info/176715/...