ios 在 UITableView 中设置滚动位置

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/413055/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 15:29:35  来源:igfitidea点击:

Setting scroll position in UITableView

iosobjective-ccocoa-touchuitableview

提问by Mustafa

I have an application that works some what similar to how iPhone's Contact application works. When we add a new Contact user is directed to a view only screen with Contact information. If we select "All Contacts" from the navigation bar, user is navigated to list of all contacts where the recently added contact is in view.

我有一个应用程序,它的工作原理与 iPhone 的联系人应用程序的工作方式类似。当我们添加一个新的联系人时,用户被定向到一个包含联系人信息的仅查看屏幕。如果我们从导航栏中选择“所有联系人”,用户将被导航到最近添加的联系人所在的所有联系人列表。

We can move the view to a particular row using:

我们可以使用以下方法将视图移动到特定行:

    [itemsTableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionBottom];

... but it's not working. I'm calling this right after calling:

......但它不起作用。我在打电话后马上打电话给:

    [tableView reloadData];

I think I'm not suppose to call selectRowAtIndexPath:animated:scrollPositionmethod here. But if not here, then where?

我想我不应该selectRowAtIndexPath:animated:scrollPosition在这里调用方法。但如果不在这里,那么在哪里?

Is there any delegate method that gets called after the following method?

在以下方法之后是否有任何委托方法被调用?

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

回答by squelart

I think I've got a similar app: A list of item., tap '+' -> new screen, come back and see the updated list, scrolled to show the added item at the bottom.

我想我有一个类似的应用程序:项目列表。点击“+”-> 新屏幕,回来查看更新的列表,滚动以在底部显示添加的项目。

In summary, I put reloadDatain viewWillAppear:animated:and scrollToRowAtIndexPath:...in viewDidAppear:animated:.

总之,我把reloadDataviewWillAppear:animated:scrollToRowAtIndexPath:...viewDidAppear:animated:

// Note: Member variables dataHasChanged and scrollToLast have been
// set to YES somewhere else, e.g. when tapping 'Save' in the new-item view.

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    if (dataHasChanged) {
        self.dataHasChanged = NO;
        [[self tableView] reloadData];
    } else {
        self.scrollToLast = NO; // No reload -> no need to scroll!
    }
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    if (scrollToLast) {
        NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:([dataController count] - 1) inSection:0];
        [[self tableView] scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
    }
}

I hope this helps. If you add something in the middle of the list, you could easily scroll to that position instead.

我希望这有帮助。如果您在列表中间添加一些内容,则可以轻松地滚动到该位置。

回答by Birju

You can try this , my application in some kind of similar to you when i click on a button scroll of uitableview is up.

你可以试试这个,当我点击 uitableview 的按钮滚动时,我的应用程序类似于你。

[tableviewname setContentOffset:CGPointMake(0, ([arrayofcontact count]-10)*cellheight) animated:YES];

10 is for how many cell you want to scroll up

10 是要向上滚动多少个单元格

Hope this will help you:-)

希望能帮到你:-)

回答by Vadim Bulavin

Scrolling animation is inevitable when offset is set from viewDidAppear(_:). A better place for setting initial scroll offset is viewWillAppear(_:). You'll need to force the layout of a table view, because it's content size is not defined at that point.

从 设置偏移量时,滚动动画是不可避免的viewDidAppear(_:)。设置初始滚动偏移的更好位置是viewWillAppear(_:). 您需要强制表格视图的布局,因为此时未定义其内容大小。

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    tableView.setNeedsLayout()
    tableView.layoutIfNeeded()

    if let selectedIndexPath = selectedIndexPath, tableView.numberOfRows(inSection: selectedIndexPath.section) > 0 {
        tableView.scrollToRow(at: selectedIndexPath, at: .top, animated: false)
    }
}

回答by Dan Morgan

Do you have enough dummy contacts added to test the scrolling? It seems that only when your tableView is of a certain size the iPhone finds the inputus to scroll.

您是否添加了足够的虚拟联系人来测试滚动?似乎只有当您的 tableView 具有特定大小时,iPhone 才能找到要滚动的 inputus。

This is the code that works for me in my project. I use a previous button and therefore I scroll the tableview a little bit further down that it usually would go with UITABLEVIEWSCROLLPOSITION. (my previous button won't work if it can't "see" the previous cell.

这是在我的项目中对我有用的代码。我使用上一个按钮,因此我将 tableview 向下滚动一点,它通常会与 UITABLEVIEWSCROLLPOSITION 一起使用。(如果它不能“看到”上一个单元格,我的上一个按钮将不起作用。

Ignore some of the custom method calls.

忽略一些自定义方法调用。

- (void)textFieldDidBeginEditing:(UITextField *)textField {

    //Show the navButtons
    [self navButtonAnimation];


    DetailsStandardCell *cell = (DetailsStandardCell *)textField.superview.superview.superview;

    self.parentController.lastCell = cell;


    //Code to scroll the tableview to the previous indexpath so the previous button will work. NOTE previous button only works if its target table cell is visible.
    NSUInteger row = cell.cellPath.row;
    NSUInteger section = cell.cellPath.section;

    NSIndexPath *previousIndexPath = nil;


    if (cell.cellPath.row == 0 && cell.cellPath.section != 0) //take selection back to last row of previous section
    {
    NSUInteger previousIndex[] = {section -1, ([[self.sections objectForKey:[NSNumber numberWithInt:section - 1]]count] -1)};
    previousIndexPath = [[NSIndexPath alloc] initWithIndexes:previousIndex length:2];   
    }
    else if (cell.cellPath.row != 0 && cell.cellPath.section != 0)
    {
        NSUInteger previousIndex[] = {section, row - 1};
        previousIndexPath = [[NSIndexPath alloc] initWithIndexes:previousIndex length:2];       

    }


    [self.theTableView scrollToRowAtIndexPath: cell.cellPath.section == 0 ? cell.cellPath : previousIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];

}