Ios 加载更多在uitableview上向上滚动的项目

Ios 加载更多在uitableview上向上滚动的项目,ios,uitableview,Ios,Uitableview,我正在制作一个带有注释的UITableView。我在底部有最新的评论,在顶部有较老的评论 我正在将注释保存在NSMutableArray中。当我到达顶部时,我想加载更多的旧评论。我如何才能做到这一点?您需要一些方法: 获取方法- 这取决于您如何实现数据检索。默认情况下,只显示最近的10条评论。如果您的数组只包含这10条注释,那么您需要一种机制来执行本地或远程数据库的获取,以提取另外10条注释并将它们添加到数组中。如果数组始终包含与该帖子相关的所有评论(在本例中为56条评论),则无需额外获取,尽管

我正在制作一个带有注释的
UITableView
。我在底部有最新的评论,在顶部有较老的评论


我正在将注释保存在
NSMutableArray
中。当我到达顶部时,我想加载更多的旧评论。我如何才能做到这一点?

您需要一些方法:

获取方法- 这取决于您如何实现数据检索。默认情况下,只显示最近的10条评论。如果您的数组只包含这10条注释,那么您需要一种机制来执行本地或远程数据库的获取,以提取另外10条注释并将它们添加到数组中。如果数组始终包含与该帖子相关的所有评论(在本例中为56条评论),则无需额外获取,尽管有人可能会认为检索和存储用户可能永远看不到的评论是低效的。为了显示正确数量的评论,需要进行一些数学运算,但我将在稍后讨论这个问题

更新表格- 查看顶部单元格时,您需要调用
[tableView reloadData]
,因为将显示更多数据。根据数组是否只包含要显示的注释或与帖子相关的所有注释,您可能还需要调用上面的fetch方法。例如,如果您的数组只包含10条注释,而您需要提取额外的10条注释,那么您首先需要执行提取,提取完成后,您需要调用
reloadData
。如果数组包含所有56条注释,则需要更新
numCommentsToShow
属性,如下所述,然后立即调用
reloadData

更新触发器- 查看顶部单元格时需要调用重新加载表的方法;但是,您不希望在视图首次出现时立即调用重载表。实现这一点的方法有很多种,这实际上取决于您是否希望在顶部单元格部分可见、完全可见甚至即将被查看时显示其他注释(这实际上可能对用户来说是最干净的)。一个简单的实现(但不一定是最理想的)是在
cellForIndexPath
方法中包含更新表的调用。如果
indexPath.row
为0,则调用update。您需要首先测试视图是否在允许更新之前加载。您还希望返回到的单元格包含更新之前出现的注释,因为在获取之后将再次调用
cellForIndexPath
方法。如果希望单元格在允许更新之前完全可见,可以执行以下操作:

数学- 如果数组只包含要显示的注释,我实际上会使
NSMutableArray
成为
NSArray
。当您获得获取结果时,我会将这20条注释保存在一个全新的数组中,并让comment数组属性仅引用新数组。然后调用
reloadData
。否则,在用户滚动时向
NSMutableArray
添加注释对我来说有点危险,但我可能错了。顺便说一句,有些人实际上可能只对接下来的10条评论(即11-20条评论)执行抓取,但如果你允许用户编辑他们的评论,我会检索1-20条评论,因为最近的评论是最有可能更改的评论。获取之后,数组将包含20条注释,它们的顺序应该是从最少到最近。这使得
cellForIndexPath
方法变得简单,它应该只在索引
indexPath.row
处检索每个单元格的注释。当前正在查看的单元格(与更新前的单元格相同)的索引将等于刚刚提取的新项目数

如果数组包含与帖子相关的所有评论(在我的示例中为56),那么您需要有一个属性,该属性包含在此给定时间点显示的评论数量。当视图第一次出现时,此属性设置为某个默认数字(在我的示例中为10)。
numberOfRowsInSection
方法需要返回这个属性,我将调用它
numCommentsToShow
。但是,
cellForIndexPath
需要检索数组中的正确项。如果它们是从最新到最新排序的,则实际上需要在索引处检索注释,该索引等于数组中注释的数量less
numCommentsToShow
plus
indexPath.row
。这样做会让人有点困惑。调用更新时,需要将
numCommentsToShow
增加一些增量(在我的示例中)10,但应注意不要将其增加到大于数组中的项数。因此,您实际上应该将其增加到增量和尚未显示的注释量中的最小值

滚动问题 滚动时可能会遇到一些问题,因为表格顶部的单元格实际上将成为表格的中间单元格之一。因此,在更新之后,表可能会跳转到顶部。您可以做一些数学运算,以确保在更新后设置表的滚动位置,这样用户就可以看到滚动位置没有改变,而实际上已经改变了。如果用户在表尚未更新时向下移动表,则会出现更困难的挑战

在解释如何做到这一点之前,目前的趋势似乎是避免这种情况。如果你看看facebook的应用程序,你永远不会看到一个无限的滚动到顶端。有一个按钮可以加载较新的帖子
    public class DidScrollEventArgs : EventArgs
    {
        public UIScrollView scrollView;

        public DidScrollEventArgs (UIScrollView scrollView) : base ()
        { 
            this.scrollView = scrollView;
        }
    }
    public event EventHandler<DidScrollEventArgs> DidScroll;
    public override void Scrolled (UIScrollView scrollView)
    {
        if (DidScroll != null)
            DidScroll.Invoke (this, new DidScrollEventArgs (scrollView));
    }
        source.DidScroll += async (object sender, MessageSource.DidScrollEventArgs e) => {

            nfloat height = e.scrollView.ContentSize.Height;
            nfloat contentYoffset = e.scrollView.ContentOffset.Y;

            if (contentYoffset == 0 && source.model.Count > 0 && height > MyBounds.Height && !isLoading && isMore) {

                isLoading = true;

                DateTime cutOff = source.model[0].SentDate.Value;

                //fetch more content
                List<MessageModel> newModels = await MessageAccess.GetMessagesAsync(ThreadId, cutOff, true);
                if (newModels.Count == 0){
                    isMore = false;
                    tableView.TableHeaderView = null;

                    isLoading = false;
                    return;
                }

                //add it on to the front of the current content
                models = newModels.Concat(source.model).ToList();
                source.model = models;

                tableView.ReloadData();

                //calculate where to scroll to (new height - old height)
                nfloat yOffset = tableView.ContentSize.Height - height;

                //scroll there
                tableView.SetContentOffset(new CGPoint(0, yOffset), false);

                isLoading = false;

            }
        };