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

时间:2017-08-07 21:32:37

标签: ios uiview constraints subviews

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

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

1 个答案:

答案 0 :(得分:1)

所以我认为你的自动调整掩码与你的约束相冲突。那并从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)当所有这一切都完成后,不要忘记从它的superview或你传递的视图中删除toastView,因为即使alpha为0,它仍然存在。