天道酬勤,学无止境

How can I get scrollViewDidScrollToTop to work in a UITableView?

I think the title explains it all. I want to be notified when a user scrolls to the top of a tableview.

I've tried the following with no luck and even added a UIScrollViewDelegate to the .h file.

- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView{
    NSLog(@"ScrolledToTop");
}

Thanks!

Edit: I can get it to call if I press the status bar. But not if I scroll to the top. Weird... could it have something to do with the tableview bouncing when it reaches the top?

评论

What happens if you try this?

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (scrollView.contentOffset.y == 0)
        NSLog(@"At the top");
}

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {

if (indexPath.row == 0 && indexPath.section == 0 ) {
    NSLog(@"Showing top cell");

}

Is that close enough?

The func scrollViewDidScroll(_ scrollView: UIScrollView) delegate method will do the trick but it gets called each time the scrollview moves a point. A less hyperactive alternative could be this:

func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>){
    if targetContentOffset.memory.y == 0.0 {
       println("Reached the Top")
}

It lets the delegate know the scrollView will reach the top before it actually gets there, and because targetContentOffset is a pointer you can change its value to adjust where the scrollview finishes its scrolling animation.

Two more options that might be simpler based on your situation are:

First, if you're trying to detect the result of an animation only, triggered either by animating contentOffset yourself or by making a call to UITableView scrollToRowAtIndexPath:, or UICollectionView scrollToItemAtIndexPath:, implement

-(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
    // You're now at the end of the scrolling animation
}

This will not not be called after a manual scroll with your finger, which may or may not be helpful sometimes.

Second, if you're trying to do something like infinite scrolling, where you refresh the list when you get to the top, or load another page of results when you get to the bottom, an easy way to do it is to just use make the call in your data source cellForRowAtIndexPath: which might save you the need to implement the delegate all together.

Do it in Swift:

func scrollViewDidScroll(scrollView: UIScrollView) {
    print(scrollView.contentOffset.y) 
}

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • iPhone操作系统:删除/重新添加后,点击状态栏滚动到顶部不起作用(iPhone OS: Tap status bar to scroll to top doesn't work after remove/add back)
    问题 使用此方法隐藏状态栏: [[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES]; 将“隐藏”设置回NO时,从顶部滚动到顶部(在UIWebView,UITableView等中)不再起作用,并且需要重新启动应用程序才能恢复功能。 这是一个错误(无论如何我还是提出了一个标准)还是错过了一步? 我可能应该期待这种行为,因为statusBar在各个视图中都以某种方式“失去了联系”? 回答1 重新显示后,您可以尝试再次将ScrollsToTop属性设置为true: [currentView setScrollsToTop:YES]; 如果这不起作用,那么您肯定只显示一种视图吗? 如果有多个滚动视图,则忽略scrollViewDidScrollToTop消息... 回答2 在iOS 5.0中,您可以访问UIWebView的scrollview属性。 webView.scrollView.scrollsToTop = YES; 回答3 亚历克斯(Alex)的以下修复对我有用。 谢谢! ((UIScrollView *)[[webView subviews] objectAtIndex:0]).scrollsToTop = NO; 急着进行此修复非常有效,但是,给我更多的时间
  • 如何检查UITableView完成滚动的时间(how to check when UITableView is done scrolling)
    问题 有没有一种方法可以检查我的tableview是否刚刚完成滚动? table.isDragging和table.isDecelerating是我只能找到的两种方法。 我不确定如何在tableview完成滚动时预测或得到通知。 我可以以某种方式使用计时器每秒检查tableView是否滚动吗? 回答1 您将实现UIScrollViewDelegate协议方法,如下所示: - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { if (!decelerate) { [self scrollingFinish]; } } - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { [self scrollingFinish]; } - (void)scrollingFinish { //enter code here } 迅捷版 public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { if decelerate {
  • scrollsToTop 不适用于 UIViewController 包含(scrollsToTop not working with UIViewController containment)
    问题 使用SDK 6.1,Xcode 4.6.1,我创建了一个新项目Master-Detail iOS App,ARC,没有故事板。 然后在DetailViewController ,在viewDidLoad我添加了UIViewController包含的两个UITableView ,并确保第二个像这样隐藏: - (void)viewDidLoad { [super viewDidLoad]; UIViewController *lViewController1 = [[UIViewController alloc] init]; UITableView *lTableView1 = [[UITableView alloc] initWithFrame: self.view.frame]; lTableView1.scrollsToTop = YES; [lViewController1.view addSubview: lTableView1]; lTableView1.dataSource = self; [self.view addSubview: lViewController1.view]; [self addChildViewController: lViewController1]; UIViewController *lViewController2 = [
  • UIScrollView + UIWebView = NO scrollsToTop(UIScrollView + UIWebView = NO scrollsToTop)
    问题 它看起来像一个可以有简单解决方案的问题,但我没有找到任何可能导致它的问题。 我在 UIScrollView 内部使用 UIWebView 并且点击 statusBar (将内容滚动到顶部)不起作用。 我做了一个简单的测试应用程序,看看它是否真的是 UIWebViews 错误。 确实如此。 // scrolls to top on status bar tap UIScrollView *sv = [[UIScrollView alloc] init]; sv.frame = CGRectMake(0, 0, 320, 480); sv.contentSize = CGSizeMake(320, 1200); [self.view addSubview:sv]; // doesn't scroll UIScrollView *sv = [[UIScrollView alloc] init]; sv.frame = CGRectMake(0, 0, 320, 480); sv.contentSize = CGSizeMake(320, 1200); UIWebView *wv = [[UIWebView alloc] init]; wv.frame = CGRectMake(0, 0, 320, 100); [sv addSubview:wv]; [self.view
  • Imitate Facebook hide/show expanding/contracting Navigation Bar(Imitate Facebook hide/show expanding/contracting Navigation Bar)
    问题 在新的iOS7 Facebook iPhone应用程序中,当用户向上滚动时, navigationBar逐渐隐藏起来,使其完全消失。 然后,当用户向下滚动时, navigationBar逐渐显示自己。 您将如何自己实施这种行为? 我知道以下解决方案,但它会立即消失,并且与用户的滚动手势速度完全无关。 [navigationController setNavigationBarHidden: YES animated:YES]; 我希望这不是重复的,因为我不确定如何最好地描述“扩展/收缩”行为。 回答1 @peerless提供的解决方案是一个很好的开始,但是它仅在拖动开始时才启动动画,而无需考虑滚动速度。 与在Facebook应用程序中获得的体验相比,这带来了更加混乱的体验。 为了匹配Facebook的行为,我们需要: 隐藏/显示导航栏,其速度与拖动速度成比例如果在部分隐藏栏时滚动停止,则启动动画以完全隐藏栏随着导航栏的缩小,淡化导航栏的项目。 首先,您需要以下属性: @property (nonatomic) CGFloat previousScrollViewYOffset; 这是UIScrollViewDelegate方法: - (void)scrollViewDidScroll:(UIScrollView *)scrollView { CGRect frame =
  • 在Swift中,我如何拥有一个具有内部和外部委托的UIScrollView子类?(In Swift, how do I have a UIScrollView subclass that has an internal and external delegate?)
    问题 我对UIScrollView进行了子类化,以添加一些功能,例如双击缩放和用于图库目的的image属性。 但是为了完成图像部分,我的子类必须是其自己的委托并实现viewForZoomingInScrollView 。 但是,当有人使用我的滚动视图子类时,他们可能还希望获取委托通知,以查看scrollViewDidScroll或您拥有的内容。 在Swift中,我如何同时获得这两个? 回答1 这是此模式的Swift版本: 尽管在Swift中已禁用forwardInvocation:但我们仍然可以使用ForwardingTargetForSelector: class MyScrollView: UIScrollView { class _DelegateProxy: NSObject, UIScrollViewDelegate { weak var _userDelegate: UIScrollViewDelegate? override func respondsToSelector(aSelector: Selector) -> Bool { return super.respondsToSelector(aSelector) || _userDelegate?.respondsToSelector(aSelector) == true } override func
  • 如何以编程方式缩放UIScrollView?(How do I programmatically zoom a UIScrollView?)
    问题 我想以基类不支持的方式进行缩放。 例如,在收到双击时。 回答1 在玩弄东西并使它工作之后,我正在回答自己的问题。 Apple在其有关如何处理双击的文档中提供了一个非常简单的示例。 进行程序缩放的基本方法是自己完成,然后告诉UIScrollView您已完成。 调整内部视图的框架和边界。 将内部视图标记为需要显示。 告诉UIScrollView有关新内容的大小。 计算缩放后应显示的内部视图部分,并使UIScrollView平移到该位置。 另一个要点:一旦告诉UIScrollView您新的内容大小,它似乎就重置了当前缩放级别的概念。 您现在处于新的1.0缩放系数。 因此,您几乎肯定会想要重置最小和最大缩放系数。 回答2 停止重新发明轮子! 看看苹果是怎么做到的! ScrollViewSuite-> Apple文档页面 ScrollViewSuite直接链接-> XcodeProject 这正是您想要的。 干杯! 回答3 注意:这太过时了。 它是从iOS 2.x时代开始的,实际上已经在iOS 3.x中得到了修复。 将其保留在此处仅出于历史目的。 我想我找到了一个干净的解决方案,我做了一个UIScrollView子类来封装它。 可以在github.com/andreyvit/ScrollingMadness上获得示例代码,这些代码说明了程序化缩放(+双击处理)和照片库样式的分页+缩放
  • 如何在UITableView中隐藏第一节标题(分组样式)(How to hide first section header in UITableView (grouped style))
    问题 随着使用分组样式的表格视图的设计在iOS 7中发生了很大变化,我想隐藏(或删除)第一个节标题。 到目前为止,我还没有设法实现它。 经过某种程度的简化,我的代码如下所示: - (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { if (section == 0) return 0.0f; return 32.0f; } - (UIView*) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { if (section == 0) { UIView* view = [[UIView alloc] initWithFrame: CGRectMake(0.0f, 0.0f, 640.0f, 0.0f)]; return view; } return nil; } - (NSString*) tableView:(UITableView *) tableView titleForHeaderInSection:(NSInteger)section { if (section == 0) { return nil; } else { // return
  • 如何从 UITableView iphone 获取 UITableView IndexPath?(How get UITableView IndexPath from UITableView iphone?)
    问题 在我的 iPhone 应用程序中,我有一个消息屏幕。 我在UIViewController上添加了UITapGestureRecognizer并且我在屏幕上有一个UITableview 。 我想选择UITableViewCell但我无法选择UITableView因为UITapGestureRecognizer 。 当我触摸屏幕时,只有点击手势动作被调用,但UITableView委托didSelectRowAtIndexPath:没有被调用。 任何人都可以帮我处理点击手势和UITableView:didSelectRowAtIndexPath: 。 提前致谢。 回答1 虽然我更喜欢 Matt Meyer 的建议或我使用自定义手势识别器的其他建议,但另一个不涉及自定义手势识别器的解决方案是让您的点击手势识别器识别您是否点击了 tableview 中的单元格,如果是,则手动调用didSelectRowAtIndexPath ,例如: - (void)handleTap:(UITapGestureRecognizer *)sender { CGPoint location = [sender locationInView:self.view]; if (CGRectContainsPoint([self.view convertRect:self.tableView.frame
  • touchesBegan 不能在 UITableView 上工作(touchesBegan not working on UITableView)
    问题 我在全屏上有UITableView 。 我想知道的是找到我单击单元格的位置。 我想要做的是在单击任何单元格时显示复制选项。 为此我试过 - (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { //some code } 但是这个方法没有被调用。 知道如何在UITableView找到用户触摸 回答1 如果您只想在单击任何单元格时显示Copy选项,那么您必须去 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath tableView 的方法。 无需使用Touch event 。 使用此方法,您可以使用indexPath获取所选单元格的副本。 编辑 要获取所选单元格的位置,您可以使用rectForRowAtIndexPath方法 CGRect rectInTableView = [tableView rectForRowAtIndexPath:indexPath]; 编辑2 CGRect rectInSuperview = [tableView convertRect:rectInTableView toView:[tableView superview]]; 回答2
  • UITableView完成查询数据后会收到通知吗?(Get notified when UITableView has finished asking for data?)
    问题 有什么方法可以找出UITableView何时从其数据源中查询数据? 关联的视图控制器( UITableViewController )的viewDidLoad / viewWillAppear / viewDidAppear方法在这里都不使用,因为它们都触发得太早了。 它们中的任何一个(完全可以理解)都不能保证对数据源的查询暂时已经完成(例如,直到视图滚动为止)。 我发现的一种解决方法是在viewDidAppear调用reloadData ,因为当reloadData返回时,可以确保表视图暂时完成了对数据源的所有查询。 但是,这似乎有点令人讨厌,因为我认为这会导致在首次加载数据源时两次(自动一次,由于reloadData调用而一次)要求输入相同的信息。 我要这样做的原因是我想保留UITableView的滚动位置-但要一直到像素级别,而不仅仅是到最近的行。 恢复滚动位置时(使用scrollRectToVisible:animated: ,我需要表格视图中已经有足够的数据,否则, scrollRectToVisible:animated:方法调用将不执行任何操作(如果您scrollRectToVisible:animated:调用,则会发生这种情况在任何viewDidLoad , viewWillAppear或viewDidAppear )。 回答1
  • 如何从UITableViewCell获取UITableView?(How to get UITableView from UITableViewCell?)
    问题 我有一个链接到对象的UITableViewCell ,我需要告诉该单元格是否可见。 根据我所做的研究,这意味着我需要以某种方式访问​​包含它的UITableView (从那里,有几种方法可以检查它是否可见)。 所以我想知道如果UITableViewCell有一个指针UITableView ,或是否有任何其他的方式来获得小区的指针? 回答1 为了避免检查iOS版本,请从单元格视图迭代遍历超级视图,直到找到UITableView为止: id view = [tableViewCellInstance superview]; while (view && [view isKindOfClass:[UITableView class]] == NO) { view = [view superview]; } UITableView *tableView = (UITableView *)view; 回答2 在iOS7的β5 UITableViewWrapperView是一个的上海华UITableViewCell 。 此外UITableView是的上海华UITableViewWrapperView 。 因此,对于iOS 7,解决方案是 UITableView *tableView = (UITableView *)cell.superview.superview; 因此,对于iOS
  • Get data from a PList into UITableView?
    I want to maintain a list of records, for each one I maintain the same type of data. I want to use this data in 2 different places: UITableView that takes from each record the "Name" value UIViewController that takes all the data to use in different fields. I assume I should be using a plist to store the data; I also assume that the object that should be receiving the data for the UITableView is NSArray so I can use the cellForRowAtIndexPath method to create the table automatically. So i created the plist "PLForArr.plist": It seems that i can only get a NSDictionary when calling the plist
  • 如何从单元格获取UITableViewCell indexPath?(How to get UITableViewCell indexPath from the Cell?)
    问题 我如何从单元格中获取其UITableView indexPath ? 我已经搜索了堆栈溢出和谷歌,但是所有的信息都是相反的。 有什么方法可以访问superView / UITableView ,然后搜索单元格? 有关上下文的更多信息:我有两个类,一个称为Cue ,一个称为CueTableCell (这是UITableViewCell的子类) CueTableCell是Cue的可视化表示(这两个类彼此之间都有指针)。 Cue对象位于链接列表中,并且当用户执行某些命令时,需要选择下一个Cue的可视表示形式( CueTableCell )。 因此, Cue类在列表中的下一个Cue上调用select方法,该方法从cell检索UITableView并调用其selectRowAtIndexPath:animated:scrollPosition:为此它需要UITableViewCell的indexPath 。 回答1 NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; 即使有人认为这是有争议的,它也有助于阅读UITableView文档(请参阅下面的评论)。 该单元不知道其索引路径是什么。 控制器应包含基于数据模型操纵UI元素或基于UI交互来修改数据的任何代码。 (请参阅MVC。) 回答2
  • 无法让 UiTableView 工作(Can't make UiTableView work)
    问题 我正在从事一个关于 XCode 6 和 Swift 的项目。 我需要将 UITableView 添加到 UIViewController,然后用内容填充表格。 因此,在我的默认 UIViewController 上,我添加了一个 UITableView 和一个 UITableViewCell(使用故事板)。 接下来,我将 UIViewController 设置为表的数据源和委托。 最后,我将此代码添加到我的视图 controller.swift 中: import UIKit class ViewController: UITableViewController, UITableViewDataSource, UITableViewDelegate { @IBOutlet var table: UITableView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that
  • 如何在UITableView中设置分隔符的全宽(How to set the full width of separator in UITableView)
    问题 我有一个UITableView ,其中分隔符没有完整的宽度。 它结束于左侧之前的10像素。 我在viewDidLoad()玩这个代码。 self.tableView.layoutMargins = UIEdgeInsetsZero; 同样在情节提要中,您可以选择自定义或默认选择器。 现在,所有填充的单元格都没有全角选择器,但空单元格则具有全角选择器。 我怎样才能解决这个问题? 回答1 这在使用Xcode 6.4和Swift 1.2的iOS 8.4-9.0设备上为我工作: func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { var cell = UITableViewCell() cell.preservesSuperviewLayoutMargins = false cell.separatorInset = UIEdgeInsetsZero cell.layoutMargins = UIEdgeInsetsZero return cell } Swift 5更新: cell.preservesSuperviewLayoutMargins = false cell.separatorInset =
  • 带有不带cellForRowAtIndexPath的静态单元格的UITableView。 如何设置清晰的背景?(UITableView with static cells without cellForRowAtIndexPath. How to set clear background?)
    问题 我有一个静态的UITableView,所有内容都布置在情节提要上。 在cellForRowAtIndexPath中,我只是使用 return [super tableView:tableView cellForRowAtIndexPath:indexPath]; 并且tableview很棒。 但是,我想将单元格背景设置为[UIColor clearColor]我该怎么做? 该表有30个单元格,每个单元格都不相同。 谢谢 回答1 我不确定这是否行得通,因为我从未尝试使用super来管理单元。 如果您的代码与super ,那么您应该可以通过设置背景颜色来摆脱困境: - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath]; cell.backgroundColor = [UIColor clearColor]; return cell; } 无论哪种方式,在我看来这都是一种奇怪的做事方式。 通常,根据默认的UITableView boiletplate代码
  • 动态调整单元格大小时如何获取 UITableView 的高度?(How to get height of UITableView when cells are dynamically sized?)
    问题 我有一个带有动态大小的单元格的 UITableView。 这意味着我已经设置: tableView.estimatedRowHeight = 50.0 tableView.rowHeight = UITableViewAutomaticDimension 现在我想获得整个表格视图的高度。 我尝试通过tableView.contentSize.height获取它,但这只返回估计的行高,而不是表视图的实际动态高度。 如何获取整个表格视图的动态高度? 回答1 我终于找到了一个解决方案: tableView.contentSize.height不适用于动态单元格,因为它们只会返回单元格数 * estimatedRowHeight 。 因此,要获得动态表格视图高度,您需要查找所有可见单元格,并总结它们的高度。 请注意,这仅适用于比屏幕短的表格视图。 但是,在我们执行上述查找可见单元格之前,重要的是要知道注意我们需要在屏幕上获取表格视图,以便我们可以获得可见单元格。 为此,我们可以为 table view 设置一个任意大的高度约束,以便它出现在屏幕上: 设置表格视图约束的高度: // Class variable heightOfTableViewConstraint set to 1000 heightOfTableViewConstraint = NSLayoutConstraint
  • 从 PList 获取数据到 UITableView?(Get data from a PList into UITableView?)
    问题 我想维护一个记录列表,对于每一个我维护相同类型的数据。 我想在 2 个不同的地方使用这些数据: UITableView从每条记录中获取“名称”值 UIViewController将所有数据用于不同领域。 我假设我应该使用 plist 来存储数据; 我还假设应该接收UITableView数据的对象是NSArray所以我可以使用cellForRowAtIndexPath方法自动创建表。 所以我创建了 plist "PLForArr.plist": 似乎我只能在使用调用 plist 时获得 NSDictionary NSString *path = [[NSBundle mainBundle] pathForResource:@"PLForArr" ofType:@"plist"]; NSArray * myArr = [[NSArray alloc] initWithContentsOfFile:path]; //doesn't work... NSDictionary * myDict = [[NSDictionary alloc] initWithContentsOfFile:path]; //does work, but who to I make a NSArray out of it / or get the data from here to the
  • 如何知道UITableview行号(How to know the UITableview row number)
    问题 我有一个带有UISwitch的UITableViewCell作为每个单元的附件UISwitch 。 当我在一个单元格中更改开关的值时,如何知道开关在哪一行? 在切换值更改事件中,我需要行号。 回答1 标签,子类或视图层次结构导航工作太多! 。 在您的操作方法中执行以下操作: CGPoint hitPoint = [sender convertPoint:CGPointZero toView:self.tableView]; NSIndexPath *hitIndex = [self.tableView indexPathForRowAtPoint:hitPoint]; 只要发件人的原点在单元格的框架内(感谢rob!),通常就可以使用任何类型的视图,多节表,无论您可以扔给它什么。 它在UITableView Swift扩展中: extension UITableView { func indexPath(for view: UIView) -> IndexPath? { let location = view.convert(CGPoint.zero, to: self) return self.indexPathForRow(at: location) } } 回答2 如果将tag属性设置为行号(如其他答案所建议),则每次都必须在tableView