【问题标题】:Programmatically force a UIScrollView to stop scrolling, for sharing a table view with multiple data sources以编程方式强制 UIScrollView 停止滚动,以便与多个数据源共享表格视图
【发布时间】:2010-11-02 10:50:07
【问题描述】:

我有一个 UITableView,当用户触摸分段控件时,它的数据源和委托在几个自定义数据源对象之间切换(想想应用商店应用中的“Top Paid”与“Top Free”)。

每个数据源对象保存它的最后滚动内容偏移量,并在它成为表格视图的活动数据源时通过执行以下操作恢复它:

tableView.contentOffset = CGPointMake(0, savedScrollPosition);

这在用户在表格静止时切换数据源时效果很好,但是如果用户在表格仍在移动(即减速)时点击分段控件,表格视图会继续从旧的偏移量开始减速,有效地覆盖了我的 contentOffset 分配。

有没有办法在我设置 contentOffset 时强制表格视图停止滚动/减速,或者有其他方法可以使这种类型的可切换数据源表格视图工作?

【问题讨论】:

    标签: iphone cocoa-touch uitableview uiscrollview


    【解决方案1】:

    你可以试试

    tableView.scrollEnabled = NO;
    tableView.scrollEnabled = YES;
    

    这可能会通过禁用滚动来停止滚动,然后再次允许它。我没有具体尝试过,但我做过类似的事情。

    【讨论】:

    • 我尝试将其设置为 NO,然后设置 contentOffset,然后将其设置回 YES。那没有用,但我不妨试试 NO-YES-offset 序列,看看是否有什么不同。
    【解决方案2】:

    您可以等待“减速”属性变为 NO(例如通过使用 KVO)并在此之后切换。

    【讨论】:

    • 这样做的问题是在设置滚动位置之前会有相当明显的延迟。
    【解决方案3】:

    您是否尝试过使用[view setContentOffset: offset animated: YES]?

    【讨论】:

    • 我会试一试。这不是我想要的行为(我希望滚动位置立即捕捉),但它可能已经足够了。
    • 适用于动画:是的。 (马上停下来)。也适用于 UICollectionViewController 上的 collectionView。
    • 这应该是公认的答案,因为它甚至使用CGPoint 作为预期问题的偏移量。
    【解决方案4】:

    一个明显的解决方法是让两个单独的表视图被交换出来,并且每个数据源都永久附加到其中一个表视图。这似乎有点浪费内存,但也许我想多了。

    【讨论】:

      【解决方案5】:

      这两种方法你试过了吗?

      它们实际上适用于“滚动”,而不仅仅是内容的偏移量。

      [self.tableView  scrollToRowAtIndexPath:savedIndexPath atScrollPosition:UITableViewScrollPositionTop animated:NO];
      

      或者:

      [self.tableView  scrollRectToVisible:savedFrame animated:NO];
      

      它们实际上应该影响滚动并通过扩展来加速表格,而不仅仅是屏幕上可见的内容。

      【讨论】:

      • scrollRectToVisible 做到了,使用保存的滚动位置作为矩形的原点,使用表格视图的边界作为高度。你是绝对正确的,滚动*方法以设置内容偏移的方式控制加速度。
      【解决方案6】:

      我使用了 Corey 的方法。我用字典表示保存和恢复矩形。此外,它可能并不明显,但要保存和恢复的矩形是 UITableView 的 bounds:

      // Save the current tableview bounds
      CGRect contentRect = self.listTableView.bounds;
      if (!!oldScope) [_contentRects setObject:(NSObject *)CGRectCreateDictionaryRepresentation(contentRect) forKey:oldScope];
      
      // Restore if possible
      CFDictionaryRef restoredFrameDict = (CFDictionaryRef)[_contentRects objectForKey:newScope];
      if (!restoredFrameDict) restoredFrameDict = CGRectCreateDictionaryRepresentation(CGRectZero);
      CGRectMakeWithDictionaryRepresentation(restoredFrameDict, &contentRect);
      
      // Switch over to new datasource
      self.listTableView.dataSource = [self dataSourceForScope:newScope];
      [self.listTableView reloadData];
      
      // Restore content offset for "newScope"; Also stops scrolling
      [self.listTableView scrollRectToVisible:contentRect animated:NO];
      

      注意CFDictionaryRef 和NSDictionary * 的可互换使用

      【讨论】:

        【解决方案7】:

        刚刚发现这个正在寻找停止我的 UIScrollView 的方法 - 我需要移动一些子视图,但如果用户轻弹屏幕并且它仍在减速,这个伤口看起来不正确。

        无论如何 - scrollRectToVisible 对我不起作用(可能是因为我没有使用表格视图??)但这非常有效:

        [mainScrollView setContentOffset:CGPointMake(mainScrollView.contentOffset.x, mainScrollView.contentOffset.y) animated:NO];
        

        然后我可以不用担心地做子视图的事情了!

        【讨论】:

          【解决方案8】:

          当我有一个 UISwitch 作为表格的选择器时,这是我的问题。但是使用分段控制我没有任何问题。也许你没有重新加载表?这是我的一段工作代码:

          NSIndexPath *exPath = [[subTable indexPathsForVisibleRows] lastObject]; 
          
          isMatchOn = [whatList selectedSegmentIndex] == 0 ? YES : NO;  //table source will make the choice looking at this BOOL  
          
          [subTable reloadData];  // here tables actually flip
          
          if (lastPosition) {
              [subTable scrollToRowAtIndexPath:lastPosition atScrollPosition:UITableViewScrollPositionBottom animated:NO];   //I scroll to saved index
              }
          self.lastPosition = exPath;  //here I save the current position
          

          【讨论】:

            【解决方案9】:

            这对我很有效:

            if (self.tableView.isDecelerating) {
                    NSArray *paths = [self.tableView indexPathsForVisibleRows];
                    [self.tableView scrollToRowAtIndexPath:[paths objectAtIndex:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
            
                }
            

            【讨论】:

              【解决方案10】:

              当你达到某个tableView.contentOffset.y值时,你也可以做self.tableView.isScrollEnabled = true/false

              【讨论】:

                猜你喜欢
                • 2011-03-25
                • 2015-08-28
                • 2011-12-13
                • 2011-01-15
                • 1970-01-01
                • 1970-01-01
                • 2010-09-26
                相关资源
                最近更新 更多