我有一个关于 iOS 和 AutoLayout 的问题...这是一个测试应用程序,我在其中复制了该问题。它由一个简单的 View Controller 组成,包含一个固定的 UIButton
;当用户单击此按钮时,委托(delegate)必须创建一个自定义 View ,应用它的定位约束;然后 View 有一个方法来构建他的内容 View ,并且 subview 也被放置有约束。
这是代码:
//MyViewController.m
@implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIButton *start_but = [[UIButton alloc] initWithFrame:CGRectMake(10, 10, 100, 40)];
[start_but setTitle:@"Draw" forState:UIControlStateNormal];
[start_but setTitleColor:[UIColor yellowColor] forState:UIControlStateNormal];
[start_but addTarget:self action:@selector(clickAction:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:start_but];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)clickAction: (id)sender
{
localView = [[MyView alloc] initWithFrame:CGRectMake(0, 0, 400, 300)];
UIView *superview = (UIView*)localView;
superview.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:localView];
NSLayoutConstraint *constr = [NSLayoutConstraint constraintWithItem:localView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:100.0];
[self.view addConstraint:constr];
constr = [NSLayoutConstraint constraintWithItem:localView
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeRight
multiplier:1.0
constant:-50.0];
[self.view addConstraint:constr];
[localView CreateGuiInterface];
}
@end
//MyView.m
@implementation MyView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
// Initialization code
}
return self;
}
-(void)CreateGuiInterface
{
UIView *superview = self;
self.backgroundColor = [UIColor redColor];
UIButton *but1 = [[UIButton alloc] init];
[but1 setTitle:@"Button" forState:UIControlStateNormal];
[but1 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
but1.backgroundColor = [UIColor yellowColor];
but1.translatesAutoresizingMaskIntoConstraints = NO;
[superview addSubview:but1];
NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:but1
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeRight multiplier:1.0
constant:-20.0];
[superview addConstraint:constraint];
constraint = [NSLayoutConstraint constraintWithItem:but1
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:50.0];
[superview addConstraint:constraint];
UILabel *label = [[UILabel alloc] init];
label.text = @"Label";
label.backgroundColor = [UIColor greenColor];
label.textColor = [UIColor blackColor];
label.translatesAutoresizingMaskIntoConstraints = NO;
[superview addSubview:label];
constraint = [NSLayoutConstraint constraintWithItem:label
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:but1
attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:-40.0];
[superview addConstraint:constraint];
constraint = [NSLayoutConstraint constraintWithItem:label
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:but1
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:20.0];
[superview addConstraint:constraint];
}
@end
所以,问题是当我点击 iOS 时似乎无法绘制 View 背景颜色。这很奇怪,因为如果我不使用superview.translatesAutoresizingMaskIntoConstraints = NO
并将 View 放在固定位置(例如 initWithFrame:CGRect(100,200,300,400)
)而不使用约束,它工作得很好:在 subview 和父 View 中使用约束会出现问题吗? AppleDoc 说约束不能穿过 View 屏障;所以我用面向本地 View 的约束编写了我的应用程序......
有人可以帮助我吗?
感谢建议
最佳答案
使用 autoLayout 的目的是永远不必在任何 View 上设置 Frame。如果您想以编程方式将 View 放置在 super View 中,您将为此提供约束。我所做的更改您将看到背景为预期的红色。我没有更改您的 MyView 实现(只是添加 -(void)CreateGuiInterface; 在 MyView.h 中)。我要演示的更改位于您的 MyViewController 实现中。
尝试使用以下代码代替您的 viewController:
@interface MyViewController ()
@property (nonatomic, strong) MyView* localView;
@end
@implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIButton *start_but = [[UIButton alloc] init];
start_but.translatesAutoresizingMaskIntoConstraints = NO;
[start_but setTitle:@"Draw" forState:UIControlStateNormal];
[start_but setTitleColor:[UIColor yellowColor] forState:UIControlStateNormal];
[start_but addTarget:self action:@selector(clickAction:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:start_but];
// The following constraints simply place the initial start button in the top left
NSDictionary* views = NSDictionaryOfVariableBindings(start_but);
NSString* format = @"H:|-[start_but]";
NSArray* constraints = [NSLayoutConstraint constraintsWithVisualFormat:format
options:0
metrics:nil
views:views];
[self.view addConstraints:constraints];
format = @"V:|-[start_but]";
constraints = [NSLayoutConstraint constraintsWithVisualFormat:format
options:0
metrics:nil
views:views];
[self.view addConstraints:constraints];
}
- (void)clickAction: (id)sender
{
self.localView = [[MyView alloc] init];
UIView *superview = (UIView*)self.localView;
superview.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.localView];
// Here I'm placing your parent view (MyView) 50 points on right of the superview with
// a width of 400 points
NSDictionary* views = NSDictionaryOfVariableBindings(superview);
NSString* format = @"H:[superview(==400)]-(50)-|";
NSArray* constraints = [NSLayoutConstraint constraintsWithVisualFormat:format
options:0
metrics:nil
views:views];
[self.view addConstraints:constraints];
// Vertically 100 points from the top of the superview with a height of 300 points
format = @"V:|-(100)-[superview(==300)]";
constraints = [NSLayoutConstraint constraintsWithVisualFormat:format
options:0
metrics:nil
views:views];
[self.view addConstraints:constraints];
[self.localView CreateGuiInterface];
}
@end
关于ios - autoLayout 和约束问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19998386/