调整UITableView标头的大小并包含UITextView(iOS7 + AutoLayout)

svg*_*in3 10 iphone objective-c uitableview ios autolayout

我一直在努力解决这个问题,我想确保我这样做是正确的.作为参考,我使用AutoLayout和Storyboard,它是一个仅限iOS7的应用程序.

我有一个带标题视图的UITableView,并且HeaderView的UI连接在故事板中.我在故事板中留下了标题,它包含一些元素,其中一个是不可滚动的UITextView.

以下是它在故事板中的基本外观截图:

截图

我将标题视图的背景变暗为深灰色,因此它很突出.

UITextView的文本可以是动态的,因此其高度需要根据文本的大小而改变.但棘手的部分是表的标题视图也需要调整其高度,具体取决于文本的大小.我已经尝试了一些带有约束的不同东西,但它并没有真正正常工作(除非我禁用AutoLayout并以编程方式重新调整大小,我真的很想避免).

当然,我希望尽可能使用尽可能少的代码.我并不依赖于使用表视图标题,尽管它可以很好地满足我的需求,因为我希望它和它包含的textview能够滚动下面的实际细节.但总而言之,如果有一种更简单的方法来实现这一目标(即使用uilabel),我将很乐意改变基础结构.

对方法的任何想法?没有找人帮助我的答案; 如果可能的话,只是寻找一些好的起点.提前致谢!

MAN*_*rii 33

前段时间我找到了新的解决方案,也许它需要调整动画并且是实验性的,但是,对于某些情况它很好,所以试一试:

  1. 将headerView添加到UITableView.
  2. 将一个子视图添加到headerView,让我们称之为包装器.
  3. 使用它的子视图(通过自动布局)调整包装器的高度.
  4. 当autolayout完成布局时,将headerView的高度设置为包装器的高度.(见-updateTableViewHeaderViewHeight)
  5. 重新设置headerView.(见-resetTableViewHeaderView)

这是一些代码:

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    [self updateTableViewHeaderViewHeight];
}

/**
 tableView's tableViewHeaderView contains wrapper view, which height is evaluated
 with Auto Layout. Here I use evaluated height and update tableView's
 tableViewHeaderView's frame.

 New height for tableViewHeaderView is applied not without magic, that's why 
 I call -resetTableViewHeaderView.
 And again, this doesn't work due to some internals of UITableView, 
 so -resetTableViewHeaderView call is scheduled in the main run loop.
*/
- (void)updateTableViewHeaderViewHeight
{
    // get height of the wrapper and apply it to a header
    CGRect Frame = self.tableView.tableHeaderView.frame;
    Frame.size.height = self.tableHeaderViewWrapper.frame.size.height;
    self.tableView.tableHeaderView.frame = Frame;

    // this magic applies the above changes
    // note, that if you won't schedule this call to the next run loop iteration
    // you'll get and error
    // so, I guess that's not a clean solution and could be wrapped in @try@catch block
    [self performSelector:@selector(resetTableViewHeaderView) withObject:self afterDelay:0];
}

// yeah, guess there's something special in the setter
- (void)resetTableViewHeaderView
{
    // whew, this could be animated!
    [UIView beginAnimations:@"tableHeaderView" context:nil];

        self.tableView.tableHeaderView = self.tableView.tableHeaderView;

    [UIView commitAnimations];
}
Run Code Online (Sandbox Code Playgroud)

所有这些在初始自动布局通过后无缝地工作.之后,如果您更改包装器的内容以使其获得不同的高度,则由于某种原因它不会起作用(猜测布局UILabel需要几个自动布局通道或其他东西).我通过在下一个运行循环迭代中为ViewController的视图调度setNeedsLayout解决了这个问题.

我为此创建了示例项目:TableHeaderView + Autolayout.