我正在尝试以编程方式将一个子视图添加到视图控制器中,但似乎我在视图控制器的viewDidLoad
中添加了子视图,因为视图中的子视图未添加在视图控制器中。
但是,如果我在视图控制器的[self.view addSubview:myUIView]
方法中移动init
,则会呈现所有内容。
另外,如果我在viewDidAppear
中调用相同的方法,我会获得所有渲染的元素,但是在显示视图控制器之后,我就可以看到元素在视图控制器中呈现的时间。 / p>
这将是我的视图控制器:
//interface
@class RLJSignInView;
@protocol RLJSignInViewControllerDelegate;
@interface RLJSignInViewController : UIViewController <UITextFieldDelegate>
@property (nonatomic, readwrite) RLJSignInView *signInView;
@property (nonatomic, assign) id<RLJSignInViewControllerDelegate> delegate;
@end
//implementation
#import "RLJSignInViewController.h"
#import "RLJSignInView.h"
#import "RLJSignInViewControllerDelegate.h"
#import "UIColor+RLJUIColorAdditions.h"
@implementation RLJSignInViewController
- (id)init
{
self = [super init];
if (self) {
_signInView = [[RLJSignInView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:self.signInView];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"%@", self.signInView);
[self.view setBackgroundColor:[UIColor rgbWithRed:250 green:250 blue:250]];
}
@end
这就是我的观点:
//interface
@interface RLJSignInView : UIView
@property (strong, nonatomic, readwrite) UITextField *username;
@property (strong, nonatomic, readwrite) UITextField *password;
@property (strong, nonatomic, readwrite) UIButton *signIn;
@property (strong, nonatomic, readwrite) UIButton *signUp;
@end
//implementation
#import "RLJSignInView.h"
#import "UITextField+RLJUITextFieldAdditions.h"
#import "UIButton+RLJUIButtonAdditions.h"
@implementation RLJSignInView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
CGRect usernameInputFrame = CGRectMake(10.0, 40.0, self.bounds.size.width - 20, 40);
CGRect passwordInputFrame = CGRectMake(10.0, 79.0, self.bounds.size.width - 20, 40);
CGRect signInButtonFrame = CGRectMake(10.0, 160, self.bounds.size.width - 20, 40);
CGRect signUpButtonFrame = CGRectMake(10.0, 220, self.bounds.size.width - 20, 40);
UIView *usernameInputLeftView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 10.0, 40)];
UIView *passwordInputLeftView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 10.0, 40)];
self.username = [[UITextField alloc] initWithFrame:usernameInputFrame
textAlignment:NSTextAlignmentLeft
textColor:[UIColor blackColor]
clearButton:UITextFieldViewModeWhileEditing
leftView:usernameInputLeftView
placeholder:@"Username"
backgroundColor:[UIColor whiteColor]
strokeWidth:2.0
strokeColor:[UIColor lightGrayColor]
keyboardType:UIKeyboardTypeEmailAddress
byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight
cornerRadii:CGSizeMake(4.0, 4.0)
secure:NO];
self.password = [[UITextField alloc] initWithFrame:passwordInputFrame
textAlignment:NSTextAlignmentLeft
textColor:[UIColor blackColor]
clearButton:UITextFieldViewModeWhileEditing
leftView:passwordInputLeftView
placeholder:@"Password"
backgroundColor:[UIColor whiteColor]
strokeWidth:2.0
strokeColor:[UIColor lightGrayColor]
keyboardType:UIKeyboardTypeDefault
byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight
cornerRadii:CGSizeMake(4.0, 4.0)
secure:YES];
self.signIn = [[UIButton alloc] initWithFrame:signInButtonFrame
title:@"Sign In"
colorNormal:[UIColor whiteColor]
colorHighlighted:[UIColor whiteColor]
colorDisabled:[UIColor whiteColor]
backgroundNormal:[UIColor colorWithRed:82 / 255.0 green:156 / 255.0 blue:201 / 255.0 alpha:1.0]
cornerRadius:4.0];
self.signUp = [[UIButton alloc] initWithFrame:signUpButtonFrame
title:@"Sign Up"
colorNormal:[UIColor blackColor]
colorHighlighted:[UIColor blackColor]
colorDisabled:[UIColor blackColor]
backgroundNormal:[UIColor whiteColor]
cornerRadius:4.0];
[self addSubview:self.username];
[self addSubview:self.password];
[self addSubview:self.signIn];
[self addSubview:self.signUp];
}
return self;
}
@end
我不确定我能做些什么,但我确信我不希望在初始化时将视图添加到子视图中。
或许我正在将视图的子视图呈现错误。如果有人遇到同样的事情,或者注意到我搞砸了什么,我会很感激这方面的一些意见。
答案 0 :(得分:2)
请勿在{{1}}方法内拨打self.view
。这会在init
方法返回之前触发viewDidLoad
,这是不正确的行为。
相反,请遵循以下模式:
init
中创建对象(属性/实例变量),或者使用延迟实例化init
viewDidLoad
这种模式可以避免你在这里发布的错误,并为你成功处理轮换和调整事件大小做好准备。
答案 1 :(得分:1)
关键可能是你过早使用self.view.bounds。当你提供初始大小的框架时(例如IB会这样做),它可能会起作用。
init
太早了。视图控制器正在初始化,视图尚未加载,这意味着没有视图,边界将返回CGRectZero
。
viewDidLoad
依赖视图的界限还为时尚早。该视图刚刚加载,它还没有超级视图,可能会在以后调整大小。
viewWillAppear
是您可以依赖视图边界的第一刻。因为它将根据autoresizingmasks或autolayout约束进行调整。
您可以在viewDidLoad
中添加子视图,但是您应该提供一个初始帧(并设置正确的自动调整大小或约束)它应该都可以正常工作。