如果在viewDidLoad中添加为子视图,则永远不会呈现UIView

时间:2013-11-16 20:11:43

标签: ios objective-c uiview ios7 viewdidload

我正在尝试以编程方式将一个子视图添加到视图控制器中,但似乎我在视图控制器的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

我不确定我能做些什么,但我确信我不希望在初始化时将视图添加到子视图中。

或许我正在将视图的子视图呈现错误。如果有人遇到同样的事情,或者注意到我搞砸了什么,我会很感激这方面的一些意见。

2 个答案:

答案 0 :(得分:2)

请勿在{{1​​}}方法内拨打self.view。这会在init方法返回之前触发viewDidLoad,这是不正确的行为。

相反,请遵循以下模式:

  • init中创建对象(属性/实例变量),或者使用延迟实例化
  • init
  • 中添加子视图
  • viewDidLoad
  • 中设置框架

这种模式可以避免你在这里发布的错误,并为你成功处理轮换和调整事件大小做好准备。

答案 1 :(得分:1)

关键可能是你过早使用self.view.bounds。当你提供初始大小的框架时(例如IB会这样做),它可能会起作用。

init太早了。视图控制器正在初始化,视图尚未加载,这意味着没有视图,边界将返回CGRectZero

viewDidLoad依赖视图的界限还为时尚早。该视图刚刚加载,它还没有超级视图,可能会在以后调整大小。

viewWillAppear是您可以依赖视图边界的第一刻。因为它将根据autoresizingmasks或autolayout约束进行调整。

您可以在viewDidLoad中添加子视图,但是您应该提供一个初始帧(并设置正确的自动调整大小或约束)它应该都可以正常工作。