以编程方式强制UIScrollView停止滚动,以共享具有多个数据源的表视图

时间:2009-06-12 12:33:19

标签: iphone cocoa-touch uitableview uiscrollview

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

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

tableView.contentOffset = CGPointMake(0, savedScrollPosition);

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

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

10 个答案:

答案 0 :(得分:19)

您尝试过这两种方法吗?

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

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

OR:

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

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

答案 1 :(得分:13)

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

答案 2 :(得分:5)

这对我很有用:

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

    }

答案 3 :(得分:4)

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

无论如何 - scrollRectToVisible对我不起作用(也许是因为我没有使用表格视图?)但这完美地运作了:

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

然后我可以毫不担心地进行子视图!

答案 4 :(得分:2)

我使用了Corey的方法。我救了&使用字典表示恢复rects。此外,它可能不是很明显,但保留& amp; restore是UITableView的界限

// 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];

请注意CFDictionaryRefNSDictionary *

的可互换使用

答案 5 :(得分:0)

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

答案 6 :(得分:0)

一个显而易见的解决方法是让两个单独的表视图被换出,每个数据源永久地附加到其中一个表视图。这似乎有点浪费记忆,但也许我过度思考了。

答案 7 :(得分:0)

当我有一个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

答案 8 :(得分:0)

当您达到某个class Program { static void Main(string[] args) { var b = new Base { IntOnBase = 1 }; var overlay = new Overlay(); overlay.Base = b; var super = overlay.Super; var intValue = super.IntOnBase; super.StringOnSuper = 8; var stringValue = super.StringOnSuper; System.Diagnostics.Debug.WriteLine(stringValue); super.NoProblem(); } } [StructLayout(LayoutKind.Explicit)] public struct Overlay { [FieldOffset(0)] public Super Super; [FieldOffset(0)] public Base Base; } public class NewClass { public string cat { get; set; } } public class Super : Base { private Super imNull; public Super() { // imNull = new Super(); System.Diagnostics.Debug.WriteLine("well i get initialized..."); } public int StringOnSuper { get; set; } public void NoProblem() { System.Diagnostics.Debug.Write("You know, I am really a " + this.GetType().Name + " kind of class. But my super is " + imNull.ToString() ); } } public class Base { public int IntOnBase { get; set; } } 值时,您也可以self.tableView.isScrollEnabled = true/false

答案 9 :(得分:-3)

您可以尝试

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

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