如何正确添加和显示UIView

时间:2016-11-11 13:44:14

标签: ios objective-c uiview addsubview

当我点击按钮时,我尝试显示复选标记(GitHub WVCheckMark)。这是代码,只有当我第二次点击按钮时它才有效。

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    mark = [[WVCheckMark alloc] init];//WithFrame:CGRectMake(50, 50, 100, 100)];
    mark.backgroundColor = [UIColor clearColor];

    //[mark setFrame:CGRectMake(100, 100, 100, 100)];
    //[self.view addSubview:mark];
}

- (IBAction) btnShow{

    [mark setFrame:CGRectMake(100, 100, 100, 100)];
    [self.view addSubview:mark];
    [mark setNeedsDisplay];
    [mark updateConstraints];
    [mark setNeedsLayout];

    [mark start];
}

如果在viewDidLoad中使用addSubview,我的工作方式(点击并显示)。

调用此方法无济于事。

[mark setNeedsDisplay];
[mark updateConstraints];
[mark setNeedsLayout];

是否可以添加子视图并将其显示在一个代码位置?

完整代码

#import "ViewController.h"
#import "TestCheckmark-Swift.h"

@interface ViewController ()

@end

WVCheckMark *mark;

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    mark = [[WVCheckMark alloc] initWithFrame:CGRectMake(50, 50, 100, 100)];
    mark.backgroundColor = [UIColor clearColor];

    [mark setFrame:CGRectMake(100, 100, 100, 100)];
    //[self.view addSubview:mark];
}

- (IBAction) btnShow{

    //[mark setFrame:CGRectMake(100, 100, 100, 100)];
    //[self.view addSubview:mark];
    [mark setNeedsDisplay];
    [mark updateConstraints];
    [mark setNeedsLayout];

    [mark start];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end

1 个答案:

答案 0 :(得分:0)

简短回答:OP代码无需在添加的视图上调用setNeedsDisplaysetNeedsLayoutupdateConstraints,但确实需要调用addSubview:父视图,如[self.view addSubview:mark];

但是要深入一点,看起来GitHub上的WVCheckMark是UIView的子类。这是一个很好的,重要的事情,因为这意味着我们可以依靠从UIView继承的一些理想的东西。

例如,.alpha属性,这是一种改变可见性的好方法,而不会弄乱视图层次结构(添加和删除子视图)。关于.alpha的另一个好处是 - 与.hidden不同 - alpha可以设置动画。

因此,让我们在一个地方设置视图层次结构和框架。关键的想法 - 以及可能最令OP代码混淆的想法 - 是致电addSubview:。懒惰地进行设置是确保我们在需要的时候完成一次的好方法。

- (WVCheckMark *)mark {
    WVCheckMark *mark = [self.view viewWithTag:64];  // 64 must be non-zero and unique amongst self.view subviews
    if (!mark) {
        mark = [[WVCheckMark alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
        mark.tag = 64;  // so we can find it later
        mark.backgroundColor = [UIColor clearColor];
        // start out invisible
        mark.alpha = 0.0;
        // important, addSubview, which is probably the main problem in the OP
        [self.view addSubview:mark];
    }
    return mark;
}

现在,无论何时需要显示/隐藏该视图,只需执行以下操作:

self.mark.alpha = 1.0;  // show
self.mark.alpha = 0.0;  // hide

由于该属性是可动画的,你可以得到一些像这样的幻想:

- (void)setMarkHidden:(BOOL)hidden animated:(BOOL)animated {
    NSTimeInterval duration = (animated)? 0.3 : 0.0;
    CGFloat alpha = (hidden)? 0.0 : 1.0;

    [UIView animateWithDuration:duration animations:^{
        self.mark.alpha = alpha;
    }];
}

您可以丢弃所有其他与复选标记相关的代码,只需按下该按钮即可触发外观...

- (IBAction)pressed:(id)sender {
    [setMarkHidden:YES animated:YES];
}