How to set view of programatically created view co

2019-07-13 00:14发布

问题:

I am developing a game and would like to have one sprite-kit scene have its own view controller (a conclusion I've reached after much debate), and would like to avoid using storyboard (I can accomplish what I want with storyboard, but would like to learn how to do it without storyboard).

In my main view controller, after clicking a button, I have the following code

MyViewController2 *test = [[MyViewController2 alloc] init]; 
test.view = [[SKView alloc] init];
[self presentViewController: test animated:YES completion:nil];

However, this just transitions a grey screen with nothing on it (did not overwrite "-(id)init" yet). The following code gets called if I overwrite the "-(id)init" method in MyViewController2:

-(id)init
{
    NSLog(@"init overwrite works");
    SKView * skView = (SKView *)self.view;
    SKScene2 *scene = [SKScene2 sceneWithSize:skView.bounds.size];
    scene.scaleMode = SKSceneScaleModeFill;
    [skView presentScene:scene];
    return self;
}

but it won't display because I get this error:

-[UIView presentScene:]: unrecognized selector sent to instance 

I know what this error means (the presentScene can only be executed by skView and can't be executed by UIView), but even though when I create the ViewController and in its init I set views to be only SKView, I still get this error. How can I fix this? Thanks for your time and help.

回答1:

The view property is managed by the UIViewController and represents the root view. You cannot simply assign your own view at any point.

Option 1

If you wish to replace the view property with your own view you can override UIViewController's loadView method and assign the view there. It is documented in the class reference for this method:

The view controller calls this method when its view property is requested but is currently nil. This method loads or creates a view and assigns it to the view property

...

You can override this method in order to create your views manually. If you choose to do so, assign the root view of your view hierarchy to the view property

So it will look something like this:

- (void)loadView 
{
    self.view = [[SKView alloc] init];
}

Option 2

You can add your SKView as a subview.

Add a property to your view controller so you can access it when necessary:

@property (strong, nonatomic) SKView *skView;

Initialize and add it as a subview when the view is loaded:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.skView = [[SKView alloc] init];
    [self.view addSubview:self.skView];

    SKScene2 *scene = [SKScene2 sceneWithSize:self.skView.bounds.size];
    scene.scaleMode = SKSceneScaleModeFill;
    [self.skView presentScene:scene];
}