Skip to content

Instantly share code, notes, and snippets.

@stevetranby
Created November 22, 2017 13:30
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stevetranby/32ebaee5f2335832ec5882dccc57396e to your computer and use it in GitHub Desktop.
Save stevetranby/32ebaee5f2335832ec5882dccc57396e to your computer and use it in GitHub Desktop.
RootViewController snippet to support iPhone X Safe Area
@implementation RootViewController
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
// Initialize the CCEAGLView
CGFloat nscale = [[UIScreen mainScreen] nativeScale];
NSLog(@"window.nativescale = %f", nscale);
printf("window.nativescale = %f\n", nscale);
CGRect nbounds = [[UIScreen mainScreen] nativeBounds];
NSLog(@"window.nativeBounds = %@", NSStringFromCGRect(nbounds));
printf("window.nativeBounds = %f x %f\n", nbounds.size.width, nbounds.size.height);
CGRect screenBounds = [UIScreen mainScreen].bounds;
NSLog(@"screenBounds = %@", NSStringFromCGRect(screenBounds));
printf("screenBounds = %f x %f\n", screenBounds.size.width, screenBounds.size.height);
// NOTE(steve): create the background view that will display outside the safe area
UIView* backgroundView = [[UIView alloc] initWithFrame:screenBounds];
//[backgroundView setBackgroundColor:[UIColor magentaColor]]; // Debug/Test
[backgroundView setBackgroundColor:[UIColor blackColor]];
self.view = backgroundView;
// NOTE(steve): Moving into didAppear in order to have valid safe area insets
// CCEAGLView *eaglView = [CCEAGLView viewWithFrame:screenBounds
// pixelFormat: (__bridge NSString *)cocos2d::GLViewImpl::_pixelFormat
// depthFormat: cocos2d::GLViewImpl::_depthFormat
// preserveBackbuffer: NO
// sharegroup: nil
// multiSampling: NO
// numberOfSamples: 0 ];
//
// eaglView.contentScaleFactor = [[UIScreen mainScreen] nativeScale];
//
// // Enable or disable multiple touches
// [eaglView setMultipleTouchEnabled:YES];
//
// // Set EAGLView as view of RootViewController
// [self.view addSubview:eaglView];
//
// //cocos2d::GLView *glview = cocos2d::GLViewImpl::createWithEAGLView((__bridge void *)self.view);
// cocos2d::GLView *glview = cocos2d::GLViewImpl::createWithEAGLView((__bridge void *)eaglView);
//
// //set the GLView as OpenGLView of the Director
// cocos2d::Director::getInstance()->setOpenGLView(glview);
//
//
// //run the cocos2d-x game scene
// app->run();
}
- (void)safeAreaInsetsDidChange {
NSLog(@"safeAreaInsetsDidChange called ....");
}
// Implement viewDidLoad to do additional setup after loading the view
- (void)viewDidLoad {
[super viewDidLoad];
if (@available(iOS 11.0, *)) {
// This should only be necessary if you changed the return value of the property
// `BOOL preferredScreenEdgesDeferringSystemGestures`, but in limited testing needed this
[self setNeedsUpdateOfScreenEdgesDeferringSystemGestures];
} else {
// Fallback on earlier versions
}
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (@available(iOS 11.0, *)) {
[self setNeedsUpdateOfScreenEdgesDeferringSystemGestures];
} else {
// Fallback on earlier versions
}
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// NOTE(steve): may want to check if insets are valid in willappear to avoid any possible "blink" due to creating/adding view after already on screen
// NOTE(steve): could also use the LayoutGuide instead
// check for devices with safe area
CGRect safeViewBounds = self.view.bounds;
if (@available(iOS 11.0, *))
{
BOOL hasSafeArea = self.view.insetsLayoutMarginsFromSafeArea;
NSLog(@"hasSafeArea = %d", hasSafeArea);
UIEdgeInsets safeInsets = self.view.safeAreaInsets;
CGSize size = safeViewBounds.size;
CGPoint origin = safeViewBounds.origin;
NSLog(@"safeInsets = %@", safeInsets);
// NOTE(steve): remember UIView frame is "Y flipped" => origin @ top-left
safeViewBounds = CGRectMake(origin.x + safeInsets.left,
origin.y + safeInsets.top,
size.width - safeInsets.left - safeInsets.right,
size.height - safeInsets.top - safeInsets.bottom);
NSLog(@"safeViewBounds = %@", safeViewBounds);
} else {
// Fallback on earlier versions
// NOTE(steve): don't do anything for older phones
}
cocos2d::Application *app = cocos2d::Application::getInstance();
// Initialize the GLView attributes
app->initGLContextAttrs();
cocos2d::GLViewImpl::convertAttrs();
CCEAGLView *eaglView = [CCEAGLView viewWithFrame:safeViewBounds
pixelFormat: (__bridge NSString *)cocos2d::GLViewImpl::_pixelFormat
depthFormat: cocos2d::GLViewImpl::_depthFormat
preserveBackbuffer: NO
sharegroup: nil
multiSampling: NO
numberOfSamples: 0 ];
eaglView.contentScaleFactor = [[UIScreen mainScreen] nativeScale];
// Enable or disable multiple touches
[eaglView setMultipleTouchEnabled:YES];
// Set EAGLView as view of RootViewController
[self.view addSubview:eaglView];
//cocos2d::GLView *glview = cocos2d::GLViewImpl::createWithEAGLView((__bridge void *)self.view);
cocos2d::GLView *glview = cocos2d::GLViewImpl::createWithEAGLView((__bridge void *)eaglView);
//set the GLView as OpenGLView of the Director
cocos2d::Director::getInstance()->setOpenGLView(glview);
//run the cocos2d-x game scene
app->run();
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
if (glview)
{
CCEAGLView *eaglview = (__bridge CCEAGLView *)glview->getEAGLView();
if (eaglview)
{
CGSize s = CGSizeMake([eaglview getWidth], [eaglview getHeight]);
cocos2d::Application::getInstance()->applicationScreenSizeChanged((int) s.width, (int) s.height);
}
}
if (@available(iOS 11.0, *)) {
[self setNeedsUpdateOfScreenEdgesDeferringSystemGestures];
} else {
// Fallback on earlier versions
}
}
- (BOOL)shouldAutorotate {
return YES;
}
//fix not hide status on ios7
- (BOOL)prefersStatusBarHidden {
return YES;
}
- (BOOL)prefersHomeIndicatorAutoHidden {
// NOTE(steve): setting this to yes causes the defer system edge gestures to not work
//return YES;
return NO;
}
- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures
{
return UIRectEdgeAll;
// NOTE(steve): should probably just defer the bottom swipe (home gesture)
//return UIRectEdgeBottom;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment