You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Objective-C 编写横竖屏适配UIView 按Label内容自动调整高度

问题根因
  • 你采用了固定Frame硬编码的方式布局,所有控件的尺寸、位置都是基于视图初始化时的屏幕宽度计算,横竖屏切换后父视图尺寸发生变化,子控件的Frame不会自动同步更新,就会出现右侧超出屏幕、20pt边距失效的问题
  • emptyTreeView高度固定写死为400,label2高度也固定为100,没有根据文本内容动态计算高度的逻辑,无法满足高度自适应的需求
推荐解决方案:使用AutoLayout实现自适应布局

AutoLayout是iOS官方提供的适配方案,能自动监听父视图尺寸变化,不需要手动计算横竖屏的Frame,同时可以完美实现内部控件自适应高度。
完整实现代码如下:

UIView *emptyTreeView = [[UIView alloc] init];
emptyTreeView.backgroundColor = [UIColor blueColor];
// 关闭自动转约束的开关
emptyTreeView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:emptyTreeView];

UILabel *label1 =  [[UILabel alloc] init];
label1.backgroundColor = [UIColor redColor];
label1.textAlignment = NSTextAlignmentCenter;
label1.textColor = [UIColor blackColor];
label1.font = [UIFont boldSystemFontOfSize:18];
label1.numberOfLines = 1; // 单行文本设为1即可
label1.text = @"The Page Cannot be displayed.";
label1.translatesAutoresizingMaskIntoConstraints = NO;
[emptyTreeView addSubview:label1];

UILabel *label2 = [[UILabel alloc] init];
label2.backgroundColor = [UIColor whiteColor];
label2.textAlignment = NSTextAlignmentCenter;
label2.textColor = [UIColor grayColor];
label2.font = [UIFont systemFontOfSize:15];
label2.numberOfLines = 0;
label2.text = @"Please use this feature or contact your internal contact person directly.";
label2.translatesAutoresizingMaskIntoConstraints = NO;
[emptyTreeView addSubview:label2];

// 激活约束
[NSLayoutConstraint activateConstraints:@[
    // emptyTreeView约束:左右距父视图20,顶部距父视图20
    [emptyTreeView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:20],
    [emptyTreeView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-20],
    [emptyTreeView.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:20],
    
    // label1约束:顶部距emptyTreeView顶部30,左右距emptyTreeView左右30,高度固定30
    [label1.topAnchor constraintEqualToAnchor:emptyTreeView.topAnchor constant:30],
    [label1.leadingAnchor constraintEqualToAnchor:emptyTreeView.leadingAnchor constant:30],
    [label1.trailingAnchor constraintEqualToAnchor:emptyTreeView.trailingAnchor constant:-30],
    [label1.heightAnchor constraintEqualToConstant:30],
    
    // label2约束:顶部距label1底部30,左右和label1对齐,底部距emptyTreeView底部30
    [label2.topAnchor constraintEqualToAnchor:label1.bottomAnchor constant:30],
    [label2.leadingAnchor constraintEqualToAnchor:label1.leadingAnchor],
    [label2.trailingAnchor constraintEqualToAnchor:label1.trailingAnchor],
    [label2.bottomAnchor constraintEqualToAnchor:emptyTreeView.bottomAnchor constant:-30]
]];

如果你要坚持使用Frame布局,需要在viewWillLayoutSubviews方法中重新计算所有控件的Frame,同时提前计算文本的自适应高度,示例逻辑如下:

// 注意需要把emptyTreeView、label1、label2声明为当前类的成员变量
- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];
    CGFloat viewWidth = self.view.frame.size.width;
    // 更新emptyTreeView的Frame
    CGFloat emptyTreeWidth = viewWidth - 40;
    emptyTreeView.frame = CGRectMake(20, 20, emptyTreeWidth, 0);
    // 更新label1 Frame
    CGFloat labelWidth = emptyTreeWidth - 60;
    label1.frame = CGRectMake(30, 30, labelWidth, 30);
    // 计算label2的自适应高度
    CGSize label2Size = [label2.text boundingRectWithSize:CGSizeMake(labelWidth, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:label2.font} context:nil].size;
    label2.frame = CGRectMake(30, 90, labelWidth, label2Size.height);
    // 更新emptyTreeView的总高度
    CGFloat totalHeight = 30 + 30 + 30 + label2Size.height + 30;
    CGRect emptyFrame = emptyTreeView.frame;
    emptyFrame.size.height = totalHeight;
    emptyTreeView.frame = emptyFrame;
}

内容的提问来源于stack exchange,提问作者iOSDude

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 08:09:00