这篇文章主要讲述如何完成一个网页视图和列表视图组合的布局问题。
相信很多iOS开发者都有一些困惑,当我们需要在UITableView中实现一些复杂的界面布局时,除了通常能想到的UITableViewCell的self-sizeing。其实UITableViewHeaderView也是能够充分利用起来的。
但是关于用UITableViewHeaderView,最大的坑在于UITableView并不会根据UITableViewHeaderView的高度去动态调整自己的高度,举个列子来说吧:比如你初始化了一个高度为100的UITableViewHeaderView,之后你直接通过修改headerView的高度是没有用的。你需要重新给tableView设置一个新高度的headerView:
UIView *headerView = self.contentTableView.tableHeaderView;
headerView.frame = CGRectMake(0, 0, ScreenW, 200);
[self.contentTableView setTableHeaderView:headerView];
先看一下我项目中实现的效果。我的布局是整体一个UITableView。页面布局分为两套。第一套是笔记内容,第二套是笔记评论。笔记内容里面包括标题视图,富文本视图,附件视图,其中富文本视图是一个webView。我将笔记内容整体作为一个headView设置给tableView。笔记评论则是cell。当webView不断加载的时候,需要动态的更新整个UITableViewHeaderView的高度。
如何获取到UIWebView的加载高度呢 ?网上有很多说通过webViewDidFinishLoad方法来获取。但如果你的UIWebView样式是通过本地的html文件渲染的(这个html映射了本地文件中的css样式文件和js一些操作事件)。webViewDidFinishLoad方法会在第一次加载html文件时就执行,你获取到的高度依然是其初始化时设置的高度。应该通过KVO来实现,既精确又方便:
#pragma mark - 监听webView的加载高度
-(void)webViewDidFinishLoad:(UIWebView *)webView{
if (!self.isObserving) {
[self startObservingHeight];
}
}
- (void)startObservingHeight
{
[self.noteContentView.scrollView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];
self.isObserving = YES;
}
- (void)stopObservingHeight
{
[self.noteContentView.scrollView removeObserver:self forKeyPath:@"contentSize" context:nil];
self.isObserving = NO;
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
if ([keyPath isEqualToString:@"contentSize"]) {
//获取webView的高度
NSLog(@"%f",self.noteContentView.scrollView.contentSize.height);
//更新webView的高度
self.noteContentView.height = self.noteContentView.scrollView.contentSize.height;
//更新TableView
[self.tableView setTableHeaderView:self.noteContentView];
}
}
如果全部都用UITableViewCell来实现的话,那笔记内容整体作为一个Cell去处理。但是当笔记内容中包含UIWebView的时候,事情就不像这么简单了。首先如果你在UITableViewCell嵌入一个高度不固定的UIWebView,处理起来是非常麻烦的。你要考虑到高度回调的问题。因为只要网络不好,UIWebView可能一直在加载,UITableView就没法拿到准确的高度。而且当你需要处理的视图不单单是UIWebView的时候,会更麻烦。所以通常情况来讲,这种页面布局推荐使用UITableViewHeaderView去完成布局是最好的。