我有一个新项目,可以使用iOS 5+的功能,因此我选择同时使用AutoLayout和UIViewController childControllers功能。
我想创建的屏幕很简单: 1. 顶部区域有许多“复杂”的控件。 2. 底部区域是一个表格视图,用于可视化结果。
我想要的是控件区域占据所有必要的空间(即我在Interface Builder中提供的空间)。表格视图将根据需要缩小。
问题是,从XIB加载时,UIViewController.view框架始终具有0x568的大小。如果200是我在Interface Builder中配置的大小,则期望为0x200。
解决方法是使用AutoLayout,在XIB中创建了所有元素的容器视图,并在viewDidLoad方法中添加并配置约束。
我想创建的屏幕很简单: 1. 顶部区域有许多“复杂”的控件。 2. 底部区域是一个表格视图,用于可视化结果。
我想要的是控件区域占据所有必要的空间(即我在Interface Builder中提供的空间)。表格视图将根据需要缩小。
问题是,从XIB加载时,UIViewController.view框架始终具有0x568的大小。如果200是我在Interface Builder中配置的大小,则期望为0x200。
解决方法是使用AutoLayout,在XIB中创建了所有元素的容器视图,并在viewDidLoad方法中添加并配置约束。
-(void) setupConstraints
{
NSMutableArray *constraints = [NSMutableArray arrayWithCapacity:1];
// Views dictionary.
UIView *topView = self.topView;
UIView *table = self.tableTracks;
NSDictionary *views = NSDictionaryOfVariableBindings(topView, table);
// Views metrics.
NSNumber *topViewHeight = [NSNumber numberWithFloat:self.topView.frame.size.height];
NSDictionary *metrics = NSDictionaryOfVariableBindings(topViewHeight);
// Pin the topView to the top edge of the container.
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[topView(==topViewHeight)][table]|" options:0 metrics:metrics views:views]];
// Pin the topView edges to both sides of the container.
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[topView]|" options:0 metrics:nil views:views]];
// Pin the table edges to both sides of the container.
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[table]|" options:0 metrics:nil views:views]];
[self.view addConstraints:constraints];
}
通过这种方式,我可以使用Interface Builder简单地调整topView
视图的大小,并且TableView
将会根据需要进行调整(没有压缩阻力,如果我们看不到表格也无所谓)。
不适用于以下情况:使用AutoLayout
和ChildControllers
因此,为了简化起见,我选择使用ChildControllers
(需要大量的插座来执行自定义UIFont设置,很遗憾XCode目前还不能处理它们!)。
我做了以下修改:
- 创建了HomeTopViewController类+ XIB。创建了HomeTableViewController类+ XIB。
- 从原始视图中复制所有视图到正确的XIB中。添加UIViewController引用并连接插座。
HomeTopViewController
的根容器配置为200px高度。- 将我的容器与子控制器的
view
插座连接。
然后我更新了我的设置代码如下:
-(void) _addChildViewControllersAndSetupConstraints {
// Get required metrics variables
NSNumber *topViewHeight = [NSNumber numberWithFloat:self.topViewController.view.frame.size.height];
CFShow(self.topViewController.view);
// log is : <UIView: 0xa209c20; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0xa2097e0>>
NSLog(@"self.topViewController.view.frame.size.height = %f", self.topViewController.view.frame.size.height);
// Informs controllers the ADD operation started
[self addChildViewController:self.topViewController];
[self addChildViewController:self.tableViewController];
// Add view to the view's hierarchy
self.topViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
self.tableViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.topViewController.view];
[self.view addSubview:self.tableViewController.view];
// Setup constraints
NSMutableArray *constraints = [NSMutableArray arrayWithCapacity:1];
// Views dictionary
UIView *topView = self.topViewController.view;
UIView *table = self.tableViewController.view;
NSDictionary *views = NSDictionaryOfVariableBindings(topView, table);
// Views metrics dictionary
NSDictionary *metrics = NSDictionaryOfVariableBindings(topViewHeight);
// Pin the topView to the top edge of the container.
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[topView(==topViewHeight)][table]|" options:0 metrics:metrics views:views]];
// Pin the topView edges to both sides of the container.
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[topView]|" options:0 metrics:nil views:views]];
// Pin the table edges to both sides of the container.
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[table]|" options:0 metrics:nil views:views]];
// Adds constraints
[self.view addConstraints:constraints];
// Informs controllers the ADD operation ended
[self.topViewController didMoveToParentViewController:self];
[self.tableViewController didMoveToParentViewController:self];
}
问题
无论我如何调整HomeTopViewController
中的UIView容器大小,当我期望200像素时,行CFShow(self.topViewController.view);
总是会给出frame = (0 0; 320 568)
。
我已将布局大小配置为“自由形式”或“无”。
尽可能避免的情况
我不想在HomeTopViewController
和HomeTableViewController
上创建其他输出口,并将初始框架/高度存储到UIViewController属性中。
问题
- 在加载时,所有controller.view.frame属性是否都在屏幕上调整大小?(无论是3.5英寸还是4英寸)
- 如何解决此问题,而不需要在某个地方硬编码大小//创建额外的输出口?