【问题标题】:UITableView scrolls up on reloadDataUITableView 在 reloadData 上向上滚动
【发布时间】:2018-07-25 14:31:25
【问题描述】:

我有一个UITableView,如果它的某些单元格中的一个按钮被点击,它就会重新加载。如果执行以下步骤,则会出现此问题:

  1. 点击单元格上的按钮,以便在reloadData 上点击的单元格下方显示另一个单元格。
  2. 向上滚动表格视图,使其隐藏一些上部内容。
  3. 再次点击该按钮可隐藏刚刚显示的单元格再次调用reloadData

然后表格视图向上并隐藏上部内容(整个第一个单元格和第二个单元格的一部分)。以下是部分代码:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if shouldShowImageResolutionOptions && (indexPath.row == 2 || indexPath.row == 3 || indexPath.row == 4) {
        return isLastKnownDeviceOrientationLandscape ? 60 : 80
    }
    if shouldShowImageDisplayOptions && (indexPath.row == 3 || indexPath.row == 4) {
        return isLastKnownDeviceOrientationLandscape ? 60 : 80
    }
    return isLastKnownDeviceOrientationLandscape ? tableView.frame.size.height / 2.5 + 40 : tableView.frame.size.height / 4.5 + 40
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if shouldShowImageResolutionOptions {
        return 6
    }
    if shouldShowImageDisplayOptions {
        return 5
    }
    return 3
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    switch indexPath.row {
    case 0:
        let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifiers.IntervalCell) as! IntervalCell

        cell.selectionStyle = .none
        cell.dottedSliderView.contentMode = .redraw
        cell.adjustThumbPosition()

        return cell
    case 1:
        let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifiers.SettingsCell) as! SettingsCell
        cell.selectionStyle = .none

        cell.titleLabel.text = LabelTitles.ImageResolution
        cell.choiseLabel.text = LabelTitles.HDResolutioin
        cell.onButtonTap = {
            self.shouldShowImageResolutionOptions = !self.shouldShowImageResolutionOptions
            self.shouldShowImageDisplayOptions = false
            self.menuTableView.reloadData()
        }

        return cell
    case 2:
        if(shouldShowImageResolutionOptions) {
            let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifiers.SingleSettingCell, for: indexPath) as! SingleSettingCell
            cell.selectionStyle = .none
            cell.mainSettingLabel.text = Settings.HDResolution

            return cell
        }

        let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifiers.SettingsCell) as! SettingsCell
        cell.selectionStyle = .none

        cell.titleLabel.text = LabelTitles.ImageDisplay
        cell.choiseLabel.text = LabelTitles.EnlargeImage
        cell.onButtonTap = {
            self.shouldShowImageDisplayOptions = !self.shouldShowImageDisplayOptions
            self.shouldShowImageResolutionOptions = false
            self.menuTableView.reloadData()
        }

        return cell

    case 3, 4:

        if(shouldShowImageResolutionOptions) {
            let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifiers.SingleSettingCell, for: indexPath)  as! SingleSettingCell
            cell.selectionStyle = .none
            cell.mainSettingLabel.text = indexPath.row == 3 ? Settings.HighResolution : Settings.MediumResolution

            return cell
        } else {
            let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifiers.SingleSettingCell, for: indexPath)  as! SingleSettingCell
            cell.selectionStyle = .none
            cell.mainSettingLabel.text = indexPath.row == 3 ? Settings.ShowFullImage : Settings.EnlargeImage

            return cell
        }

    case 5:

        let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifiers.SettingsCell) as! SettingsCell
        cell.selectionStyle = .none

        cell.titleLabel.text = LabelTitles.ImageDisplay
        cell.choiseLabel.text = LabelTitles.EnlargeImage
        cell.onButtonTap = {
            self.shouldShowImageDisplayOptions = !self.shouldShowImageDisplayOptions
            self.shouldShowImageResolutionOptions = false
            self.menuTableView.reloadData()
        }

        return cell

    default:
        return UITableViewCell()
    }

}

【问题讨论】:

  • 你应该使用developer.apple.com/documentation/uikit/uitableview/…而不是重新加载表格视图
  • @user3581248 感谢您的想法,我稍后会尝试并告诉它是否修复它。
  • @user3581248 我用insertRowsAtIndexPaths:withRowAnimation:deleteRowsAtIndexPaths:withRowAnimation: 更新了我的代码,它解决了这个问题。你知道为什么这对reloadData有效吗?如果您将您的建议作为答案发布,我会接受。

标签: ios swift uitableview


【解决方案1】:

来自UITableViewreloadData 方法文档(https://developer.apple.com/documentation/uikit/uitableview/1614862-reloaddata):

表视图的委托或数据源在它希望表视图完全重新加载其数据时调用此方法。 不应在插入或删除行的方法中调用它,尤其是在通过调用 beginUpdates 和 endUpdates 实现的动画块中。

有专门的插入/删除行方法用于插入和删除:

因此,当您重构代码以使用这些代码时,它应该可以顺利且按预期工作。

【讨论】:

    猜你喜欢
    • 2019-06-12
    • 1970-01-01
    • 1970-01-01
    • 2011-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多