2011-01-30 2 views
0

Я пытался понять контроллеры просмотра и представления, и даже после просмотра некоторых классов в iTunesU у меня все еще есть проблемы с их программным обеспечением. Я надеюсь, кто-то может немного разъяснить.Нужна помощь в понимании программно созданного UIView и UIViewController

Так что я пытаюсь создать UIViewController, который, в свою очередь, создает его представление.

Программа разбита на следующие классы: ProgramNameAppDelegate.h и .m ApplicationRootViewController.h и .m

С AppDelegate, я создаю UIWindow и UIViewController. Частичный код выглядит следующим образом:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    // Override point for customization after application launch. 
    _window = [ [UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    if (!_window) 
    { 
     [self release]; 
     return NO; 
    } 

    _rootViewController = [ [ApplicationRootViewController alloc] init]; 
    if (!_rootViewController) 
    { 
     NSLog(@"No _rootViewController"); 
     [self release]; 
     return NO; 
    } 

    [_window addSubview:[_rootViewController view]]; 
    [_window makeKeyAndVisible]; 

    return YES; 
} 

В ApplicationRootViewController я вызываю init. Мой UIView создан в loadView как таковой:

- (void)loadView 
{ 
    NSLog(@"In loadView"); 

    [super loadView]; 

    CGRect _frame = [[UIScreen mainScreen] applicationFrame]; 

    UIView* _rootView = [[UIView alloc] initWithFrame:_frame]; 

    [_rootView setBackgroundColor:[UIColor redColor]]; 

    self.view = _rootView; 

    return; 

} 

Проблема у меня, видимо, программа создает вид, однако, никогда не показывая вид, что я создал, пока приложение не уйдет в отставку активно. Как только я выхожу из приложения и вернусь, вид есть. Я пробовал несколько других вещей, но он всегда ведет себя одинаково.

В конечном итоге я хотел бы, чтобы контроллер создал представление из подкласса UIView.h и .m-файла.

Спасибо,

Кевин

+0

Есть что-то, что вы не разместили или не упомянули, потому что ваш код работает хорошо для меня. Кстати, у вас есть утечка здесь: self.view = _rootView; вам нужно освободить _rootView – Max

+0

Да, я поймал утечку памяти. Остальная часть кода - довольно консервированный материал. Я исправил проблему, но я до сих пор не знаю, что происходит. Я работал в новейшем предварительном просмотре XCode (хотя я думаю, что это не имело к этому отношения). Я отказался от кода и переписал его в текущем выпуске XCode, и теперь все работает так, как должно. Я провел день, вытаскивая волосы. Спасибо, что посмотрели на него. – Kevin

+0

Где и когда вызывается запрос loadView? – hotpaw2

ответ

1

От docs:

Вашей пользовательской реализации loadView метода не должен назвать супер.

Таким образом, избавиться от [super loadview] и он должен работать;)

Кроме того, если вы хотите использовать пользовательский вид (подкласс UIView). Alloc/Init с использованием initWithFrame: и при обращении к себе.Вид с UIViewController вы должны бросить его так:

[(MyView *)self.view myMethod]; 

Как все просто;)

EDIT: Предположим, что вы делаете класс как это:

//MyView.h 
@interface MyView : UIView{ 
    ... 
} 
- (void) doSomething:(NSString *)string; 
@end 
//MyView.m 
#import MyView.h 
@implementation MyView 
... write your implementation here 
@end 

затем в UIViewController, в loadView do:

//don't forget to #import "MyView.h" 
-(void) loadView{ 
    MyView *myView = [[MyView alloc] initWithFrame:CGRectMake(...)]; 
    self.view = (UIView *)myView; 
    [myView release]; 
} 

тогда, когда речь идет ваш взгляд куда-то в контроллере:

- (void) viewDidAppear:(BOOL)animated{ 
    [super viewDidAppear:animated]; 
    [(MyView *)self.view doSomething:@"something"];//1 
    [self.view setBackgroundColor:[UIColor greenColor]];//2 
} 

В //1 вы должны бросить, потому что ваш вызываете doSomething: метод (или это может быть имущество, а), которая объявлена ​​/, определенной в MyView и не в UIView. Если вы не бросите, вы получите предупреждение, но оно будет работать. В //2 вам не нужно отбрасывать, поскольку setBackgroundColor: является методом, определенным в классе UIView;)

Objective-C является очень гибким и позволит бросить много вещей, так что вы должны быть осторожны, потому что отливка походит на сообщение компилятор: «Поверьте мне, это не UIView, это MyVIew», и компилятор будет подчиняться вам. Но если вы ошиблись, ваше приложение потерпит крах при попытке позвонить doSomething:, потому что его нет в UIView.

+0

Спасибо nacho! Я решил это, но не знал, как это сделать. Я «случайно» не учитывал [super loadview], когда я переписал код. Теперь я понимаю, почему это работает, и почему это не так. Кроме того, я наблюдал, как Matt Stoker делал много кастинга при работе с представлениями, но не мог точно понять, почему. – Kevin

+0

Я добавил объяснение о том, как настроить пользовательский вид на uiviewcontroller;) ... – nacho4d

Смежные вопросы