UIView 的 viewDidLoad?
Posted
技术标签:
【中文标题】UIView 的 viewDidLoad?【英文标题】:viewDidLoad for UIView? 【发布时间】:2013-04-22 11:27:56 【问题描述】:UIView
对应的 viewDidLoad
是什么?
我有一个带有 xib 的 UIView
。我想在加载时隐藏其中一个子视图。
我试过用这个。
- (id)initWithCoder:(NSCoder *)aDecoder
....
_theView.hidden = YES;
但此时子视图_theView
为零。
This answer 没有帮助我,因为在创建 UIViewController
的那一刻,UIView
尚未创建。它是稍后以编程方式创建的。
【问题讨论】:
如果您的 UIView 是“稍后以编程方式创建的”,此时删除您的子视图 我希望所有与 UIView 相关的代码都位于 UIView 的类中 接受的答案具有误导性。我添加了更详细的答案。 @Segev,请阅读我的评论 【参考方案1】:试试
-awakeFromNib
方法
或者在 xib 中为您的子视图设置隐藏视图属性
【讨论】:
@Luda 我认为这个答案对于你的问题来说仍然足够了。为什么现在有赏金......似乎很早就结束了?【参考方案2】:AwakeFromNib
仅在从 nib 文件加载视图时调用。
所有视图都调用layoutSubviews
,您可以在layoutSubviews
函数中添加bool _loaded = yes;
并知道视图是否加载。
【讨论】:
记得在所有这些方法上调用 super :D awakeFromNib 总是会被调用,这里真的没有必要使用layoutSubviews
。
@Segev,因此,如果在使用 nib 或情节提要时调用 awakeFromNib,如果以编程方式创建视图,则不会调用它?只有 .h 和 .m 或 .swift。如果是这样,那么你的答案是错误的,并且 awakeFromNib 并不总是被调用。【参考方案3】:
接受的答案具有误导性。 awakeFromNib 将始终被调用,而不仅仅是在使用 nib 时。 来自苹果文档:
awakeFromNib:
在从 Interface Builder 存档,或 nib 文件。
Link
在下一个示例中,我只使用了故事板 您可以非常轻松地对此进行测试。
这是我们的 ViewController:
ViewController.m:
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
[super viewDidLoad];
NSLog(@"viewDidLoad");
-(void)awakeFromNib
NSLog(@"awakeFromNib in view controller");
@end
RedView.m:
#import "RedView.h"
@implementation RedView
-(void)awakeFromNib
NSLog(@"awakeFromNib inside RedView");
self.green.hidden = YES;
@end
打印顺序:
-
视图控制器中的 awakeFromNib
RedView 中的 awakeFromNib
viewDidLoad
当然绿色视图会被隐藏。
编辑:
如果您仅使用代码创建视图,则不会调用 awakeFromNib,但您可以自己调用它,或者更好的是,创建自己的方法。
没有 StoryBoard 的示例(仅代码):
RedView.m:
#import "RedView.h"
@implementation RedView
-(void)loadRedView
NSLog(@"loadRedView");
self.green = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
self.green.backgroundColor = [UIColor greenColor];
[self addSubview:self.green];
self.green.hidden = YES;
@end
ViewController.m:
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
[super viewDidLoad];
self.red = [[RedView alloc]initWithFrame:CGRectMake(0, 0, 200, 200)];
self.red.backgroundColor = [UIColor redColor];
[self.view addSubview:self.red];
[self.red loadRedView];
@end
【讨论】:
因此,如果在使用 nib 或情节提要时调用 awakeFromNib,如果以编程方式创建视图,则不会调用它?只有 .h 和 .m 或 .swift。如果是这样,那么您的答案是错误的,并且 awakeFromNib 并不总是被调用。 就像苹果文档建议的那样,Prepares the receiver for service after it has been loaded from an Interface Builder archive, or nib file.
所以它不会被调用,但是你可以简单地调用它自己!我已经编辑了答案。
但这是一个黑客。您建议在不涉及 nib 时调用与 nib 相关的函数
同样,该功能与 nib 无关。使用 StoryBoard 时,它的工作原理是一样的。没有什么骇人听闻的。你只要调用一个方法UIView
就知道了。您可以在视图中创建不同的方法并在加载时调用它,例如 -(void)fooIsLoading
是的,这很骇人听闻。 Storyboard 只是 nib/xib 的不同形式,因此当从 Storyboard 加载对象时也会调用 awakeFromNib。如果您可以选择自己调用 awakeFromNib,那么您也可以调用 prepareForWhatever
方法,这样可以使代码更清晰。 awakeFromNib
比 Storyboards 古老得多,甚至比 ios 还要古老,这就是为什么它有这个可能具有误导性的名称,尽管现在大多使用 Storyboards。但是文档很清楚,Storyboard 是一个 Interface Builder 存档。【参考方案4】:
一般没有这样的方法。问题是,您的_theView
来自哪里。
如果您的视图(包括其子视图)是从同一个 nib/xib/storyboard 加载的,那么您可以使用 awakeFromNib
,它将在从存档加载完整的对象层次结构后调用,因此您的 _theView
应该也可以设置。
如果您的视图是以编程方式创建的,但没有为_theView
本身创建子视图,这意味着您的代码中必须有一个位置可以添加该子视图。在这种情况下,您有两个选择
_theView
后对调用者隐藏它
或者在您的视图类上声明一个prepareForDisplay
方法(或类似方法),并在创建您的视图并分配_theView
后调用它。在prepareForDisplay
(或您选择的任何名称)方法中,您可以做任何您喜欢的事情,例如隐藏_theView
。
我不建议为此滥用layoutSubviews
,因为它用于不同的目的,并且会在视图的生命周期内被调用多次,而不仅仅是你想要的一次。是的,您可以保存之前是否调用过它,但我也认为这是一种黑客行为。在正确设置并调用它之后,最好创建您自己的方法来以您想要的方式初始化视图。
【讨论】:
很好的解释,并为我指明了正确的方向。谢谢。【参考方案5】:layoutSubviews 将调用您可以设置为隐藏的所有视图,而不是 awakeFromNib。 如果您使用的是 xib,那么您可以设置默认的隐藏属性。
【讨论】:
【参考方案6】:private var layoutSubviewsCounter = 0
override func layoutSubviews()
super.layoutSubviews()
if layoutSubviewsCounter == 0
layoutSubviewsCounter += 1
viewDidLoad()
func viewDidLoad()
// your code here
【讨论】:
以上是关于UIView 的 viewDidLoad?的主要内容,如果未能解决你的问题,请参考以下文章