UITableView:根据屏幕大小设置表格标题视图高度

时间:2015-06-25 12:05:50

标签: ios objective-c uitableview autolayout

我有一个表视图,其中包含通过同一xib中的接口构建器创建的表头视图。我想根据屏幕大小设置标题的高度,例如屏幕高度的50%。

以下是我在iPhone 4s上获得的静态高度:

Tableview header in iPhone 4s

这就是我在iPhone 6上获得的:

Tableview header in iPhone 6

请注意,标题的内容是静态的。

我无法使用自动布局为标题设置约束。我试图根据表视图的高度设置高度约束,但在界面构建器中似乎不可能。控制拖动不起作用。我无法将标题从标题拖到表格视图,甚至拖到标题本身。

enter image description here

如何根据屏幕尺寸设置标题的高度?

2 个答案:

答案 0 :(得分:9)

不幸的是,无法使用自动布局调整表标题视图的大小。您可以对标题内的元素使用自动布局,但必须通过显式设置其框架来指定标题的大小。如果标题的高度是静态的并且在编译时已知,则可以使用IB。但是,如果高度是动态的或取决于设备(如您的情况),则必须在代码中设置它。

一个非常灵活的解决方案是创建UITableView的自定义子类,并在layoutSubviews方法中调整标题的框架。这样,在调整表视图大小时,会自动调整标题的大小。但是,您必须小心,只有在实际需要更改时才重新应用标题的帧以避免无限循环。

以下是Objective-C中的内容:

@interface MyTableView : UITableView
@end

@implementation MyTableView : UITableView

- (void)layoutSubviews {
    [super layoutSubviews];

    if (self.tableHeaderView) {
        UIView *header = self.tableHeaderView;
        CGRect rect = CGRectMake(0, 0, self.bounds.size.width,
                                 self.bounds.size.height / 2);

        // Only adjust frame if needed to avoid infinite loop
        if (!CGRectEqualToRect(self.tableHeaderView.frame, rect)) {
            header.frame = rect;

            // This will apply the new header size and trigger another
            // call of layoutSubviews
            self.tableHeaderView = header;
        }
    }
}

@end

Swift版本如下所示:

class MyTableView: UITableView {

    override func layoutSubviews() {
        super.layoutSubviews()

        if let header = tableHeaderView {
            let rect = CGRectMake(0, 0, bounds.size.width, bounds.size.height / 2)

            // Only adjust frame if needed to avoid infinite loop
            if !CGRectEqualToRect(header.frame, rect) {
                header.frame = rect

                // This will apply the new header size and trigger 
                // another call of layoutSubviews
                tableHeaderView = header
            }
        }
    }

}

请注意,上述代码段使用表格视图的边界而不是屏幕大小来计算标题大小。

更新:请注意,设置layoutIfNeeded属性后,有时需要额外调用tableHeaderView。我遇到了一个问题,在标题视图上方绘制了标题标题而没有调用layoutIfNeeded

答案 1 :(得分:1)

我尝试了以下代码,它似乎适用于iOS7和iOS8。它将标题框的高度更改为屏幕高度的一半。如果标题只是表格区域大小的一半,您可能希望从/ 2之前的屏幕高度中减去导航和状态栏的高度。

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Your other code

    // Set the table header height
    CGRect headerFrame = self.tableView.tableHeaderView.frame;
    headerFrame.size.height = [[UIScreen mainScreen] bounds].size.height/2;
    self.tableView.tableHeaderView.frame=headerFrame;
}