添加 Subviews/Constraints:试图了解为什么我的子视图没有显示
Adding Subviews/Constraints: Trying to understand WHY my subviews are not showing up
我想创建一个弹出窗口,让用户知道他们是否尝试输入重复信息。所以最初我有一个会弹出和消失的 UILabel。
UILabel *toastView = [[UILabel alloc] init];
toastView.alpha = 0;
toastView.layer.cornerRadius = 4.0f;
toastView.layer.borderColor = [UIColor colorWithRed:200.0/255.0 green:199.0/255.0 blue:204.0/255.0 alpha:1].CGColor;
CGFloat scale = [[UIScreen mainScreen] scale];
if (scale == 2.0) {
// retina screen;
toastView.layer.borderWidth = 0.5;
} else {
// non-retina screen
toastView.layer.borderWidth = 1.0;
}
toastView.backgroundColor = [UIColor colorWithRed:63.0/255.0 green:63.0/255.0 blue:63.0/255.0 alpha:1];
toastView.textAlignment = NSTextAlignmentCenter;
[toastView setAdjustsFontSizeToFitWidth:YES];
toastView.text = @" E-Mail has already been added ";
toastView.font = [UIFont fontWithName:@"HelveticaNeue" size:toastView.font.pointSize];
toastView.textColor = [UIColor whiteColor];
[toastView setTranslatesAutoresizingMaskIntoConstraints:NO];
[toastView.layer setMasksToBounds:YES];
[self.superview.superview.superview addSubview:toastView];
[[UIApplication sharedApplication].keyWindow bringSubviewToFront:toastView];
[toastView.bottomAnchor constraintEqualToAnchor:self.superview.superview.superview.centerYAnchor].active = YES;
[toastView.centerXAnchor constraintEqualToAnchor:self.superview.superview.superview.centerXAnchor].active = YES;
[toastView.heightAnchor constraintEqualToConstant:round(self.superview.superview.superview.frame.size.height/12)].active = YES;
[toastView.widthAnchor constraintEqualToConstant:round(self.superview.superview.superview.frame.size.width/1.5)].active = YES;
[UIView animateWithDuration:0.3 animations:^{
toastView.alpha = 0.95;
} completion:^(BOOL finished) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[UIView animateWithDuration:0.3 animations:^{
toastView.alpha = 0;
} completion:nil];
});
}];
这很好用。然后我想添加一个图像,所以我决定将这个弹出窗口的创建移动到一个方法,该方法接受一个视图和一条消息,并生成一个带有 UILabel 和 UIImageView 的弹出视图。这是代码:
+(void)toastAlert:(UIView*)view message:(NSString*)message {
UIView *toastView = [[UIView alloc] init];
UILabel *toastLabel = [[UILabel alloc] init];
UIImage *infoImage = [UIImage imageNamed:@"info_white"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:infoImage];
toastView.alpha = 0;
toastView.layer.cornerRadius = 4.0f;
toastView.layer.borderColor = [UIColor colorWithRed:200.0/255.0 green:199.0/255.0 blue:204.0/255.0 alpha:1].CGColor;
CGFloat scale = [[UIScreen mainScreen] scale];
if (scale == 2.0) {
// retina screen;
toastView.layer.borderWidth = 0.5;
} else {
// non-retina screen
toastView.layer.borderWidth = 1.0;
}
[toastLabel setTextAlignment:NSTextAlignmentCenter];
[toastLabel setAdjustsFontSizeToFitWidth:YES];
[toastLabel setText:[NSString stringWithFormat:@"%@", message]];
[toastLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:toastLabel.font.pointSize]];
[toastLabel setTextColor: [UIColor whiteColor]];
toastView.backgroundColor = [UIColor colorWithRed:63.0/255.0 green:63.0/255.0 blue:63.0/255.0 alpha:1];
[toastView setTranslatesAutoresizingMaskIntoConstraints:NO];
[toastView.layer setMasksToBounds:YES];
[view addSubview:toastView];
[[UIApplication sharedApplication].keyWindow bringSubviewToFront:toastView];
[toastView addSubview:toastLabel];
[toastView addSubview:imageView];
[toastView.bottomAnchor constraintEqualToAnchor:view.centerYAnchor].active = YES;
[toastView.centerXAnchor constraintEqualToAnchor:view.centerXAnchor].active = YES;
[toastView.heightAnchor constraintEqualToConstant:round(view.frame.size.height/12)].active = YES;
[toastView.widthAnchor constraintEqualToConstant:round(view.frame.size.width/1.5)].active = YES;
[imageView.centerYAnchor constraintEqualToAnchor:toastView.centerYAnchor].active = YES;
[imageView.leadingAnchor constraintEqualToAnchor:toastView.leadingAnchor constant:padding].active = YES;
[imageView.heightAnchor constraintEqualToConstant:toastView.frame.size.height/2].active = YES;
[imageView.widthAnchor constraintEqualToAnchor:toastView.heightAnchor].active = YES;
[toastLabel.centerYAnchor constraintEqualToAnchor:toastView.centerYAnchor].active = YES;
[toastLabel.centerXAnchor constraintEqualToAnchor:toastView.centerXAnchor constant:imageView.frame.size.width + padding*2].active = YES;
[toastLabel.leadingAnchor constraintEqualToAnchor:imageView.trailingAnchor constant:padding].active = YES;
[toastLabel.heightAnchor constraintEqualToConstant:toastView.frame.size.height/2].active = YES;
[UIView animateWithDuration:0.3 animations:^{
toastView.alpha = 0.95;
} completion:^(BOOL finished) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[UIView animateWithDuration:0.3 animations:^{
toastView.alpha = 0;
} completion:nil];
});
}];
}
但是,无论我做什么,我都只能显示 UIView,而不会显示任何文本或 UILabel。当我添加 UIImageView 时,它显示出来但弄乱了整个 toastView 的大小调整。
我仍然是一名初级开发人员,我确定我错过了一些基本的东西...有人可以向我解释我做错了什么吗? (不仅仅是寻找一个直接的答案,因为解释更有价值)
所以我认为您的自动调整大小蒙版与您的约束冲突。然后从 CGRectZero 开始。我将尝试解决每个项目,以便您知道出了什么问题。这是工作代码。
-(void)alteredToastAlert:(UIView*)targetView message:(NSString*)message {
CGFloat padding = 10.0;
// i like to start with real frames buggy things happen with CGRectZero
UIView *toastView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 300, 200)];
//turn all resizing masks off
[toastView setTranslatesAutoresizingMaskIntoConstraints:NO];
UILabel *toastLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300, 200)];
[toastLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
UIImage *infoImage = [UIImage imageNamed:@"info_white"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:infoImage];
[imageView setTranslatesAutoresizingMaskIntoConstraints:NO];
//has a size but intrinsic
toastView.alpha = 0;
toastView.layer.cornerRadius = 4.0f;
toastView.layer.borderColor = [UIColor colorWithRed:200.0/255.0 green:199.0/255.0 blue:204.0/255.0 alpha:1].CGColor;
CGFloat scale = [[UIScreen mainScreen] scale];
if (scale == 2.0) {
// retina screen;
toastView.layer.borderWidth = 0.5;
} else {
// non-retina screen
toastView.layer.borderWidth = 1.0;
}
[toastLabel setTextAlignment:NSTextAlignmentCenter];
[toastLabel setText:[NSString stringWithFormat:@"%@", message]];
[toastLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:22]];
[toastLabel setTextColor: [UIColor whiteColor]];
[toastLabel setMinimumScaleFactor:0.01];
toastView.backgroundColor = [UIColor colorWithRed:63.0/255.0 green:63.0/255.0 blue:63.0/255.0 alpha:1];
[toastView setTranslatesAutoresizingMaskIntoConstraints:NO];
[toastView.layer setMasksToBounds:YES];
[targetView addSubview:toastView];
[[UIApplication sharedApplication].keyWindow bringSubviewToFront:toastView];
//adding here but everything has a frame so it is not size 0. Then apply autolayout
[toastView addSubview:toastLabel];
[toastView addSubview:imageView];
[toastView.bottomAnchor constraintEqualToAnchor:targetView.centerYAnchor].active = YES;
[toastView.centerXAnchor constraintEqualToAnchor:targetView.centerXAnchor].active = YES;
[toastView.heightAnchor constraintEqualToConstant:round(targetView.frame.size.height/12)].active = YES;
[toastView.widthAnchor constraintEqualToConstant:round(targetView.frame.size.width/1.5)].active = YES;
[imageView.centerYAnchor constraintEqualToAnchor:toastView.centerYAnchor].active = YES;
[imageView.leadingAnchor constraintEqualToAnchor:toastView.leadingAnchor constant:padding].active = YES;
[imageView.heightAnchor constraintEqualToConstant:toastView.frame.size.height/2].active = YES;
[imageView.widthAnchor constraintEqualToAnchor:toastView.heightAnchor].active = YES;
imageView.backgroundColor = [UIColor redColor];
[toastLabel.centerYAnchor constraintEqualToAnchor:toastView.centerYAnchor].active = YES;
[toastLabel.leadingAnchor constraintEqualToAnchor:imageView.trailingAnchor constant:padding].active = YES;
// have to have a trailing to keep it inside the view
[toastLabel.trailingAnchor constraintEqualToAnchor:toastView.trailingAnchor constant:padding].active = YES;
[toastLabel.heightAnchor constraintEqualToConstant:toastView.frame.size.height/2].active = YES;
toastView.alpha = 1;
[UIView animateWithDuration:0.3 animations:^{
toastView.alpha = 0.95;
} completion:^(BOOL finished) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[UIView animateWithDuration:0.3 animations:^{
toastView.alpha = 0;
} completion:^(BOOL finished){
//may need to remove from superview
}];
});
}];
}
1) 你会注意到我设置了框架作为开始。我这样做是因为我注意到从 CGRectZero 开始会做一些疯狂的事情。我们最终会让视图由自动布局控制,但首先我设置框架。图像视图将建立它的内在框架。
2) 接下来我告诉系统不要从自动调整掩码创建约束。我对 toastView 以及标签和图像视图都这样做。
3) 我告诉标签文本的最小比例因子,我从 22 开始,字体大小是任意的。你可能会把它提高到 50,它仍然会缩小。我想是因为 CGRectZero 你的字体大小之前是 0 但我不确定
4) 我让您的约束使用标签上的尾随约束来完成工作,但我认为仅此而已。你可以看看。
5) 当所有这些都完成后,不要忘记从它的超级视图或您传递的视图中删除 toastView,因为即使 alpha 为 0,它仍然存在。
我想创建一个弹出窗口,让用户知道他们是否尝试输入重复信息。所以最初我有一个会弹出和消失的 UILabel。
UILabel *toastView = [[UILabel alloc] init];
toastView.alpha = 0;
toastView.layer.cornerRadius = 4.0f;
toastView.layer.borderColor = [UIColor colorWithRed:200.0/255.0 green:199.0/255.0 blue:204.0/255.0 alpha:1].CGColor;
CGFloat scale = [[UIScreen mainScreen] scale];
if (scale == 2.0) {
// retina screen;
toastView.layer.borderWidth = 0.5;
} else {
// non-retina screen
toastView.layer.borderWidth = 1.0;
}
toastView.backgroundColor = [UIColor colorWithRed:63.0/255.0 green:63.0/255.0 blue:63.0/255.0 alpha:1];
toastView.textAlignment = NSTextAlignmentCenter;
[toastView setAdjustsFontSizeToFitWidth:YES];
toastView.text = @" E-Mail has already been added ";
toastView.font = [UIFont fontWithName:@"HelveticaNeue" size:toastView.font.pointSize];
toastView.textColor = [UIColor whiteColor];
[toastView setTranslatesAutoresizingMaskIntoConstraints:NO];
[toastView.layer setMasksToBounds:YES];
[self.superview.superview.superview addSubview:toastView];
[[UIApplication sharedApplication].keyWindow bringSubviewToFront:toastView];
[toastView.bottomAnchor constraintEqualToAnchor:self.superview.superview.superview.centerYAnchor].active = YES;
[toastView.centerXAnchor constraintEqualToAnchor:self.superview.superview.superview.centerXAnchor].active = YES;
[toastView.heightAnchor constraintEqualToConstant:round(self.superview.superview.superview.frame.size.height/12)].active = YES;
[toastView.widthAnchor constraintEqualToConstant:round(self.superview.superview.superview.frame.size.width/1.5)].active = YES;
[UIView animateWithDuration:0.3 animations:^{
toastView.alpha = 0.95;
} completion:^(BOOL finished) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[UIView animateWithDuration:0.3 animations:^{
toastView.alpha = 0;
} completion:nil];
});
}];
这很好用。然后我想添加一个图像,所以我决定将这个弹出窗口的创建移动到一个方法,该方法接受一个视图和一条消息,并生成一个带有 UILabel 和 UIImageView 的弹出视图。这是代码:
+(void)toastAlert:(UIView*)view message:(NSString*)message {
UIView *toastView = [[UIView alloc] init];
UILabel *toastLabel = [[UILabel alloc] init];
UIImage *infoImage = [UIImage imageNamed:@"info_white"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:infoImage];
toastView.alpha = 0;
toastView.layer.cornerRadius = 4.0f;
toastView.layer.borderColor = [UIColor colorWithRed:200.0/255.0 green:199.0/255.0 blue:204.0/255.0 alpha:1].CGColor;
CGFloat scale = [[UIScreen mainScreen] scale];
if (scale == 2.0) {
// retina screen;
toastView.layer.borderWidth = 0.5;
} else {
// non-retina screen
toastView.layer.borderWidth = 1.0;
}
[toastLabel setTextAlignment:NSTextAlignmentCenter];
[toastLabel setAdjustsFontSizeToFitWidth:YES];
[toastLabel setText:[NSString stringWithFormat:@"%@", message]];
[toastLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:toastLabel.font.pointSize]];
[toastLabel setTextColor: [UIColor whiteColor]];
toastView.backgroundColor = [UIColor colorWithRed:63.0/255.0 green:63.0/255.0 blue:63.0/255.0 alpha:1];
[toastView setTranslatesAutoresizingMaskIntoConstraints:NO];
[toastView.layer setMasksToBounds:YES];
[view addSubview:toastView];
[[UIApplication sharedApplication].keyWindow bringSubviewToFront:toastView];
[toastView addSubview:toastLabel];
[toastView addSubview:imageView];
[toastView.bottomAnchor constraintEqualToAnchor:view.centerYAnchor].active = YES;
[toastView.centerXAnchor constraintEqualToAnchor:view.centerXAnchor].active = YES;
[toastView.heightAnchor constraintEqualToConstant:round(view.frame.size.height/12)].active = YES;
[toastView.widthAnchor constraintEqualToConstant:round(view.frame.size.width/1.5)].active = YES;
[imageView.centerYAnchor constraintEqualToAnchor:toastView.centerYAnchor].active = YES;
[imageView.leadingAnchor constraintEqualToAnchor:toastView.leadingAnchor constant:padding].active = YES;
[imageView.heightAnchor constraintEqualToConstant:toastView.frame.size.height/2].active = YES;
[imageView.widthAnchor constraintEqualToAnchor:toastView.heightAnchor].active = YES;
[toastLabel.centerYAnchor constraintEqualToAnchor:toastView.centerYAnchor].active = YES;
[toastLabel.centerXAnchor constraintEqualToAnchor:toastView.centerXAnchor constant:imageView.frame.size.width + padding*2].active = YES;
[toastLabel.leadingAnchor constraintEqualToAnchor:imageView.trailingAnchor constant:padding].active = YES;
[toastLabel.heightAnchor constraintEqualToConstant:toastView.frame.size.height/2].active = YES;
[UIView animateWithDuration:0.3 animations:^{
toastView.alpha = 0.95;
} completion:^(BOOL finished) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[UIView animateWithDuration:0.3 animations:^{
toastView.alpha = 0;
} completion:nil];
});
}];
}
但是,无论我做什么,我都只能显示 UIView,而不会显示任何文本或 UILabel。当我添加 UIImageView 时,它显示出来但弄乱了整个 toastView 的大小调整。
我仍然是一名初级开发人员,我确定我错过了一些基本的东西...有人可以向我解释我做错了什么吗? (不仅仅是寻找一个直接的答案,因为解释更有价值)
所以我认为您的自动调整大小蒙版与您的约束冲突。然后从 CGRectZero 开始。我将尝试解决每个项目,以便您知道出了什么问题。这是工作代码。
-(void)alteredToastAlert:(UIView*)targetView message:(NSString*)message {
CGFloat padding = 10.0;
// i like to start with real frames buggy things happen with CGRectZero
UIView *toastView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 300, 200)];
//turn all resizing masks off
[toastView setTranslatesAutoresizingMaskIntoConstraints:NO];
UILabel *toastLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300, 200)];
[toastLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
UIImage *infoImage = [UIImage imageNamed:@"info_white"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:infoImage];
[imageView setTranslatesAutoresizingMaskIntoConstraints:NO];
//has a size but intrinsic
toastView.alpha = 0;
toastView.layer.cornerRadius = 4.0f;
toastView.layer.borderColor = [UIColor colorWithRed:200.0/255.0 green:199.0/255.0 blue:204.0/255.0 alpha:1].CGColor;
CGFloat scale = [[UIScreen mainScreen] scale];
if (scale == 2.0) {
// retina screen;
toastView.layer.borderWidth = 0.5;
} else {
// non-retina screen
toastView.layer.borderWidth = 1.0;
}
[toastLabel setTextAlignment:NSTextAlignmentCenter];
[toastLabel setText:[NSString stringWithFormat:@"%@", message]];
[toastLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:22]];
[toastLabel setTextColor: [UIColor whiteColor]];
[toastLabel setMinimumScaleFactor:0.01];
toastView.backgroundColor = [UIColor colorWithRed:63.0/255.0 green:63.0/255.0 blue:63.0/255.0 alpha:1];
[toastView setTranslatesAutoresizingMaskIntoConstraints:NO];
[toastView.layer setMasksToBounds:YES];
[targetView addSubview:toastView];
[[UIApplication sharedApplication].keyWindow bringSubviewToFront:toastView];
//adding here but everything has a frame so it is not size 0. Then apply autolayout
[toastView addSubview:toastLabel];
[toastView addSubview:imageView];
[toastView.bottomAnchor constraintEqualToAnchor:targetView.centerYAnchor].active = YES;
[toastView.centerXAnchor constraintEqualToAnchor:targetView.centerXAnchor].active = YES;
[toastView.heightAnchor constraintEqualToConstant:round(targetView.frame.size.height/12)].active = YES;
[toastView.widthAnchor constraintEqualToConstant:round(targetView.frame.size.width/1.5)].active = YES;
[imageView.centerYAnchor constraintEqualToAnchor:toastView.centerYAnchor].active = YES;
[imageView.leadingAnchor constraintEqualToAnchor:toastView.leadingAnchor constant:padding].active = YES;
[imageView.heightAnchor constraintEqualToConstant:toastView.frame.size.height/2].active = YES;
[imageView.widthAnchor constraintEqualToAnchor:toastView.heightAnchor].active = YES;
imageView.backgroundColor = [UIColor redColor];
[toastLabel.centerYAnchor constraintEqualToAnchor:toastView.centerYAnchor].active = YES;
[toastLabel.leadingAnchor constraintEqualToAnchor:imageView.trailingAnchor constant:padding].active = YES;
// have to have a trailing to keep it inside the view
[toastLabel.trailingAnchor constraintEqualToAnchor:toastView.trailingAnchor constant:padding].active = YES;
[toastLabel.heightAnchor constraintEqualToConstant:toastView.frame.size.height/2].active = YES;
toastView.alpha = 1;
[UIView animateWithDuration:0.3 animations:^{
toastView.alpha = 0.95;
} completion:^(BOOL finished) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[UIView animateWithDuration:0.3 animations:^{
toastView.alpha = 0;
} completion:^(BOOL finished){
//may need to remove from superview
}];
});
}];
}
1) 你会注意到我设置了框架作为开始。我这样做是因为我注意到从 CGRectZero 开始会做一些疯狂的事情。我们最终会让视图由自动布局控制,但首先我设置框架。图像视图将建立它的内在框架。
2) 接下来我告诉系统不要从自动调整掩码创建约束。我对 toastView 以及标签和图像视图都这样做。
3) 我告诉标签文本的最小比例因子,我从 22 开始,字体大小是任意的。你可能会把它提高到 50,它仍然会缩小。我想是因为 CGRectZero 你的字体大小之前是 0 但我不确定
4) 我让您的约束使用标签上的尾随约束来完成工作,但我认为仅此而已。你可以看看。
5) 当所有这些都完成后,不要忘记从它的超级视图或您传递的视图中删除 toastView,因为即使 alpha 为 0,它仍然存在。