iOS UIScrollView 以编程方式从下到上添加元素

Posted

技术标签:

【中文标题】iOS UIScrollView 以编程方式从下到上添加元素【英文标题】:iOS UIScrollView add elements programmatically from bottom to top 【发布时间】:2016-01-26 11:49:56 【问题描述】:

我正在尝试创建一个聊天视图,其中消息从底部添加到顶部(如 facebook)。

视图有2个状态,第一个状态是没有启用滚动(消息是从底部到顶部添加的,但是当它们离开视口时它们会消失)

第二种状态让用户滚动到顶部以查看之前的消息。

不知道我说清楚了没有,这里有一些截图:

Chat message 1Chat message 2

您能解释一下如何以编程方式执行此操作吗?实际上,它可以在没有 UIScrollView 的情况下工作,但是当我尝试让它在其中工作时,它是一团糟。

我尝试了很多不同的方法,但没有一个可以正常工作......

我不明白为什么 ScrollView 这么难用,我从来没有见过任何语言的原生组件能像这样工作......

[编辑] 我面临的最后一个问题是当我尝试隐藏每条消息(单元格)并返回到 TableView 的底部以便显示新消息时,我无法隐藏视口之外的单元格。

代码如下:

- (void)disableScrollAndHideMessages 
    [self.chatTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]
atScrollPosition:UITableViewScrollPositionBottom animated:NO];
    self.chatTableView.scrollEnabled = NO;
    self.chatTableView.bounces = NO;

    // hide messages
    for (ChatMessageViewCell *messageViewCell in visibleCells) 
        [messageViewCell hide];
    

我试图通过[self.chatTableView cellForRowAtIndexPath:i]; 上的循环隐藏每个单元格,但它崩溃了,因为无法访问视口外的单元格。

显示键盘时我遇到了同样的问题,如果消息在显示时由于计时器而消失(消息在 X 秒后自动消失),当我隐藏它时,视口外的消息仍然可见。

提前致谢!

【问题讨论】:

【参考方案1】:

我在一个类似的应用程序中很容易做到这一点......

首先,使用UITableView。表视图是为处理大量显示的项目而构建的。使用的内存仅足以在屏幕上显示所有内容。使用滚动视图,您必须将每个聊天内容加载到内存中并将其放在屏幕上。如果有数以千计的消息,那么就会占用大量内存,并且可能会导致应用程序运行缓慢或崩溃。

将其编码为像普通的UITableView 一样从上到下工作。第 0 行位于顶部,显示最新聊天消息的内容。然后是第 1 行和第 2 行,依此类推……

那就这样吧……

self.tableView.transform = CGAffineTransformMakeRotation(M_PI);

这会将 tableview 及其所有内容旋转 180 度,因此现在最新的聊天位于底部,但所有单元格都颠倒了。

因此,在单元子类中,在 init 方法中执行此操作...

self.contentView.transform = CGAffineTransformMakeRotation(M_PI);

这也会将单元格的内容旋转 180 度。这会使单元格的内容再次以正确的方式向上。

所以现在,只需 2 行代码,您就可以找到所需的内容了 :)

【讨论】:

这看起来是一种很棒的处理方式!我已经看到我可以禁用 TableView 中的滚动,所以我认为它会完成这项工作。我会尽快实现这个,如果可行的话,我可以让它成为公认的答案:) 我忘记了在添加消息时运行了一些动画。以前的消息向上移动,新消息从左侧(从屏幕开始)。使用 TableView 看起来很复杂吗?再加上每条消息的长度可能不同的事实,所以我需要相应地更改单元格高度。你怎么看? @Comawoot 您所说的是 UITableView 的内置功能。如果您的目标是 ios 8 及更高版本,则自动单元格高度内置于自动布局中。 UITableView 上有一个函数 insertRowsAtIndexPaths:withRowAnimation:UITableViewRowAnimationLeft 的动画选项会从左边开始动画行。 @Comawoot 如果您的目标是低于 iOS 8,那么您仍然可以使用 heightForRow 方法使每一行具有不同的高度。 @Comawoot 即使没有内置功能,使用表格视图仍然很容易。单元格只是视图,因此可以设置动画等等,就像任何视图都可以设置动画一样。【参考方案2】:

要完成这项工作,您应该通过新消息的高度加上间距来增加 scrollView 的 contentView 的大小,获取最后一条消息在 scrollView 的 contentView 中的位置并添加相对于该消息的新消息。你可以这样做:

scrollView.contentSize = CGSizeMake(scrollView.contentSize.width ,scrollView.contentSize.height + newMessageView.frame.size.height + spacing);
newMessageView.frame = CGRectMake(x, lastMessageView.frame.origin.y + spacing, newMessageView.frame.size.width, newMessageView.frame.size.height);
[scrollView addSubView:newMessageView];

【讨论】:

以上是关于iOS UIScrollView 以编程方式从下到上添加元素的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式 UIScrollView 不起作用

WPF 从下到上调整窗口大小

如何以编程方式增加具有约束的 UIScrollView 的高度?

以编程方式布局 UIScrollView,并为其子视图添加了自动布局,但它不滚动

从下到上显示元素,如 facebook 消息

如何创建一个从下到上包含 0 到 1 不透明度值(alpha 值)的 UIView?