简体   繁体   中英

How do views load on OSX 10.9?

I've only been developing on OSX 10.10+, I'm want my application to work on both 10.9 and 10.10+. I'm having the issue of viewDidLoad() is only available on 10.10+. How can I flexible views and view controllers to work on both?

From looking at the source code it looks like I need to override init? But when overriding init:nibName:nibBundleOrNil: but it also requires init:coder and that doesn't make much sense to me (it's undocumented in the source).

Before 10.10 the NSViewController was basically doing nothing (it was the NSWindowController doing most of the job) ;) On 10.10 it gained the methods similar from iOS world (viewDidLoad...) and one really important thing, it was finally put automatically into NSResponder chain (NSApp sendAction:... will check if the viewController has the method).

So how to get the functionality?

  1. use awakeFromNib
  2. manually add view into responder chain (if you compile with 10.10 SDK then the view is added automatically on 10.10 and later; if you compile with 10.9 SDK you have to add it manually)
  3. use XIBs; you can't use storyboards -> they use 10.10 nsviewcontrollers -> dead end

So if you use storyboards it's a lot of work. If you don't have clean MVC/MVVM architecture then it's not worth.

Alternative is to double your classes pre10.10 and after10.10 but this means having the same code layed off twice (once using storyboards, once using XIBs).

EDIT:

As @geowar suggested you can override loadView. Mind that you still can't use storyboards and you have to manually add your viewController into responderChain

- (void)loadView
{
    [super loadView];

    // if we're running on 10.8 or older…
    if (NSAppKitVersionNumber <= NSAppKitVersionNumber10_8) {
        [self viewDidLoad]; // call viewDidLoad (added in 10.9)
    }
}

Alternatively

- (void)setView:(NSView*)view {
    super.view = view;
    // if we're running on 10.8 or older…
    if (NSAppKitVersionNumber <= NSAppKitVersionNumber10_8) {
        [self viewDidLoad]; // call viewDidLoad (added in 10.9)
    }
}
@end

EDIT2:

awakeFromNib is called after loadView (which gets the new view from xib and instantiates it). As suggested by @Daij-Djan another solution is to override setter.

Advice for People who Are Looking for -viewWillLoad and -viewDidLoad Methods in NSViewController

Even though NSWindowController has -windowWillLoad and -windowDidLoad methods for you to override the NSViewController class introduced in Mac OS 10.5 does not have corresponding -viewWillLoad and -viewDidLoad methods. You can override -[NSViewController loadView] to customize what happens immediately before or immediately after nib loading done by a view controller.

在此处输入图片说明

to have thee equivalent of 10.10 on 10.9 write a VC like this

@interface MyViewController : NSViewController 
@end

@implementation MyViewController 
- (void)setView:(NSView*)v {
    super.view = v;
    // if we're running on 10.8 or older…
    if (NSAppKitVersionNumber <= NSAppKitVersionNumber10_8) {
        [self viewDidLoad]; // call viewDidLoad (added in 10.9)
    }
}
@end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM