添加子视图/约束:试图理解为什么我的子视图没有显示

问题描述:

我想创建一个弹出窗口让用户知道他们是否尝试输入重复信息。所以最初我有一个会弹出并消失的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的大小调整。

我还是一名初级开发人员,我确定我错过了一些基本的东西......任何人都可以向我解释我做错了什么吗? (不只是寻找一个直接的答案,因为解释值得更多)

+0

只是看一下手机,但你可能需要添加尾随约束toastLabel。您可能还需要设置最小比例因子。 – agibson007

所以我认为你的自动调整口罩与你的约束相冲突。那并且从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开始做一些疯狂的事情。我们最终会让视图受自动布局控制,但要开始设置帧。 imageview将建立它的内在框架。

2)接下来,我告诉系统不要从自动调整掩码创建约束。我为toastView做这个,就像标签和imageview一样。

3)我告诉标签文本的最小比例因子,我从任意字体大小的值开始为22。你可能会碰到50,它仍然会缩小。我认为,因为CGRectZero你以前的字体大小为0,但我不确定

4)我让你的约束与标签上的可能是尾随约束的版本一起工作,但我认为就是这样。你可以看看它。

5)当所有这些都完成后,请不要忘记从它的超级视图或您传递的视图中删除toastView,因为即使alpha为0,它仍然存在。

+1

是的! setTranslatesAutoresizingMaskIntoConstraints,不能相信我忘了那一个。这解决了约束问题,并在视图上设置了框架,使子视图正确显示。我也拿出了toastLabel的centerXAnchor约束条件,因为它没有必要。最后,我添加了尾随锚,并根据您的建议删除了子视图。谢谢你,先生,大部分的晚上这让我很烦恼。 –