如何正确添加和显示 UIView on tap
Posted
技术标签:
【中文标题】如何正确添加和显示 UIView on tap【英文标题】:How correct add and show UIView on tap 【发布时间】:2016-11-11 13:44:14 【问题描述】:当我点击按钮时,我尝试显示复选标记(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
【问题讨论】:
在btnShow
中调试。它被称为? (去掉三个 setNeed...updateCo...)
方法viewDidLoad
、viewWillAppear
和viewDidAppear
是根据viewCont生命周期调用的,只要在viewDidAppear
里面添加按钮,然后再应用任何代码。
@shallowThought 是的,当我第一次点击时调用 btnShow
@vaibhav,是的,这个问题更多是为了了解 viewDidAppear 中发生了什么,并且可以在 btnShow 中这样做
我认为你声明标记的方式不正确,你能告诉我们那个代码吗?
【参考方案1】:
简答:OP 代码不需要在添加的视图上调用setNeedsDisplay
、setNeedsLayout
、updateConstraints
,但它确实需要在父视图上调用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];
【讨论】:
以上是关于如何正确添加和显示 UIView on tap的主要内容,如果未能解决你的问题,请参考以下文章
Swift - 如何将点击手势添加到 UIViews 数组?