iOS Objective-C:TableView宽度与TextField一致却超出屏幕求助
嘿,这个问题我做Auto Layout适配的时候也踩过一模一样的坑,来给你理清楚原因和解决思路~
为什么会超出屏幕?
核心原因是你调用cofigureAutoComTableView的时机太早了!
因为你在Storyboard里给TextField加了Auto Layout约束,而Auto Layout的布局计算是在视图生命周期的后期完成的(比如viewDidLayoutSubviews阶段)。如果在viewDidLoad或者viewWillAppear里直接获取TextField的frame,此时它的尺寸还是Storyboard里的初始设计尺寸(比如你在Xcode里设的320px宽),而不是设备屏幕上的实际渲染尺寸。用这个错误的宽度去创建TableView,自然会出现超出屏幕的情况。
解决办法一:在正确的时机获取frame
把TableView的初始化代码放到viewDidLayoutSubviews里调用,这个方法会在Auto Layout完成所有布局计算后触发,此时TextField的frame就是最终在屏幕上显示的真实尺寸。
注意:viewDidLayoutSubviews会被多次调用(比如屏幕旋转、视图刷新时),所以要加个判断避免重复创建TableView:
- (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; // 只初始化一次TableView if (!autocompleteTableView) { [self cofigureAutoComTableView]; } } -(void)cofigureAutoComTableView { // 用TextField的实际高度代替固定的32,适配不同高度的TextField CGFloat tableViewTopY = self.txtActivity.frame.origin.y + self.txtActivity.frame.size.height; autocompleteTableView = [[UITableView alloc] initWithFrame:CGRectMake( self.txtActivity.frame.origin.x, tableViewTopY, self.txtActivity.frame.size.width, 200 ) style:UITableViewStylePlain]; // 别忘了设置数据源、代理,以及添加到父视图 autocompleteTableView.dataSource = self; autocompleteTableView.delegate = self; [self.view addSubview:autocompleteTableView]; }
解决办法二:更推荐的Auto Layout约束方式
既然你已经在用Auto Layout约束TextField,那直接给TableView也加约束是更稳妥的方案——完全不用依赖frame,适配各种屏幕尺寸和旋转场景都更省心。
代码示例:
-(void)cofigureAutoComTableView { // 初始化时用CGRectZero,后续靠约束确定位置 autocompleteTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; // 必须关闭自动转换约束,否则手动加的约束不生效 autocompleteTableView.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:autocompleteTableView]; // 添加约束:和TextField左/右对齐,顶部紧贴TextField底部,高度固定200 [NSLayoutConstraint activateConstraints:@[ [autocompleteTableView.leadingAnchor constraintEqualToAnchor:self.txtActivity.leadingAnchor], [autocompleteTableView.trailingAnchor constraintEqualToAnchor:self.txtActivity.trailingAnchor], [autocompleteTableView.topAnchor constraintEqualToAnchor:self.txtActivity.bottomAnchor constant:0], // 可调整间距 [autocompleteTableView.heightAnchor constraintEqualToConstant:200] ]]; // 设置数据源和代理 autocompleteTableView.dataSource = self; autocompleteTableView.delegate = self; }
这种方式的好处是:不管设备屏幕多大、是否旋转,TableView都会自动和TextField保持一致的宽度,完全不用关心frame的变化,符合iOS Auto Layout的设计理念。
内容的提问来源于stack exchange,提问作者Hanz Cheah

