【问题标题】:Setting scroll position in UITableView在 UITableView 中设置滚动位置
【发布时间】:2010-09-29 14:36:28
【问题描述】:

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

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

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

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

    [tableView reloadData];

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

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

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

【问题讨论】:

  • 我相信使用以下单元格状态自定义 - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{

标签: ios objective-c cocoa-touch uitableview


【解决方案1】:

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

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

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

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

}

【讨论】:

    【解决方案2】:

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

    总之,我将reloadData 放入viewWillAppear: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];
        }
    }
    

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

    【讨论】:

    • self.dataChange & self.scrollToLast 是这个 BOOL 变量。
    【解决方案3】:

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

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

    10 表示您要向上滚动多少个单元格

    希望这会对你有所帮助:-)

    【讨论】:

    • 我尝试了您的解决方案 - 我在表格中的单元格数量 (numberOfRowsInSection) 为 30,单元格高度为 172,我希望表格滚动到单元格 7。结果等式是 5504,我看到它滚动到一个空白屏幕:( 我错过了什么?
    【解决方案4】:

    当从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)
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-03
      • 2012-10-24
      • 2013-09-21
      • 1970-01-01
      相关资源
      最近更新 更多