【问题标题】:Why does UITableView contentOffset change when using segmented control?为什么使用分段控件时 UITableView contentOffset 会发生变化?
【发布时间】:2016-08-03 16:12:12
【问题描述】:

我有一个UITableView,它的导航栏中有一个分段控件。我使用相同的表格视图来显示 3 组不同的数据,基于分段控件的选定索引。我现在正在尝试保留每个段选项的滚动位置,以便每个段选项似乎都有一个表(即每个选择的结果都有独立的滚动位置)。

要执行此操作,我将为每个状态存储一个CGPoint变量,它们在选定的段索引更改时为设置为contentOffset。该变量用于在段更改时设置表格视图的内容偏移量。

However, it seems like the contentOffset value changes when the selected segment index changes without any visible change to the position within the table.就像内容偏移量的 0 位置在移动,这使我存储的值现在错误。

当我的控制器包含以下方法时:

override func viewDidLoad() {
    // set up the view here...        

    print(tableView.contentOffset)
}

@IBAction func selectedSegmentChanged(sender: AnyObject) {
    print(tableView.contentOffset)

    // code to change the data shown in the table view...
}

当视图加载时,我得到以下记录:

(0.0, 0.0)

但在更改片段后我得到:

(0.0, -64.0)

所有状态都显示表格视图滚动到完全相同的位置,即顶部。

这种行为使我无法正确存储滚动位置,因为内容偏移的“含义”似乎正在发生变化。


编辑:内容偏移量实际上在viewDidLoad()viewDidAppear() 之间调整,很可能是由于内容插入。所以我现在存储第一次调用viewDidAppear() 时的内容偏移值。

【问题讨论】:

    标签: ios swift uitableview uiscrollview uikit


    【解决方案1】:

    我刚才也遇到了这个问题,在几个场景下这个问题似乎和UITableView一致。 我的问题是当我的 UITableView 有 headerView 时引起的。 headerView 与 section 中的 Header 不同,它是 UITableView 类的属性,必须基于框架。当我的 headerView 的高度大于: [[UIScreen mainScreen] bounds].height; 我也有一个 ContentInset 设置为正常的 statusBarHeight + 44.0f 但是在我的 tableView 上执行 reloadData 之后,tableView 会自动调整它的 ContentOffset。 我的解决方案是,考虑到 UITableView 设置了 ContentOffset 以确保我的列表的开头可见。在执行reloadData 后,我会将tableView 设置为滚动到开头。 这是我的代码:

    self.headerView = [ProgramDetailsHeaderView new];
        self.headerView.frame = CGRectMake(0, 0, [Utilz deviceWidth], [ProgramDetailsHeaderView headerHeightWithModel:self.model]);
    [self.headerView setDelegate:self];
    
    self.tableView = [UITableView new];
    self.tableView.translateAutoResizingMaskIntoConstraint = NO;
    self.tableView.tableHeaderView = self.headerView;
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    self.tableView.showsVerticalScrollIndicator = NO;
    self.tableView.estimatedRowHeight = 0;
    self.tableView.contentInset = UIEdgeInsetsMake(_statusBarHeight + 44.0f, 0, [Utilz deviceBottomNotch] + 10, 0);
    [self.view addSubview:self.tableView];
    // TableView Constraints...
    
    [UIView animateWithDuration:0 animations:^{
        [weakSelf.tableView reloadData];
    } completion:^(BOOL finished) {
        [weakSelf.tableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];
    }];
    

    这不是最标准的答案,当我找到更好的方法时,我会在这里更新我的答案。

    【讨论】:

      【解决方案2】:

      设置tableviewestimatedRowHeight 修复问题 tableView.estimatedRowHeight = Cell_Row_Height

      【讨论】:

      • 这对我有用。谢谢!
      【解决方案3】:

      此问题通常是由视图控制器上的属性引起的。将其设置为 false 应该可以修复它。

      self.automaticallyAdjustsScrollViewInsets = false
      

      也可以从情节提要中设置。只需选择视图控制器并取消选中Adjusts scroll view insets

      【讨论】:

      • 谢谢 - 当我禁用 Adjusts Scroll View Insets 选项时,我在日志中得到(0,0), (0,0),这确实表明可以解决问题。但是,此视图控制器是从导航控制器链接到的,因此当禁用该选项时,我的表格中的顶部结果隐藏在导航栏下。我应该手动设置插图吗?
      • 要么你这样做,要么你改变你的逻辑以使用自动调整,任何看起来更方便的方法。
      • 如何在保持自动调整的同时更改逻辑以解决问题?有没有办法触发 contentOffset 的重新计算,以便我可以适应 -64 调整?或者有没有办法确定调整的内容?
      • 啊哈。保持自动调整,我可以通过在viewDidAppear()而不是viewDidLoad()中访问它来获得正确的起始偏移量。
      猜你喜欢
      • 2017-08-22
      • 2016-10-08
      • 1970-01-01
      • 2017-03-01
      • 2018-10-04
      • 1970-01-01
      • 1970-01-01
      • 2017-05-09
      • 1970-01-01
      相关资源
      最近更新 更多