Window turns black in OpenGL - ios

Hi I'm very new to ios and OpenGL. I'm trying to follow the instructions from the book iPhone 3d programming. I just want to render a grey screen from OpenGL.
I really don't know what I've done wrong, and I need to understand why I don't get my OpenGL window right before I can venture forth.
If I can help any further just post a comment :)
GLView.h:
#import <UIKit/UIKit.h>
#import <OpenGLES/EAGL.h>
#import <QuartzCore/QuartzCore.h>
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>
#interface GLView : UIView {
// Protected fields
EAGLContext* m_context;
}
// public fields
-(void)drawWiew;
#end
GLView.mm:
#import "GLView.h"
#implementation GLView
+(Class) layerClass {
return [CAEAGLLayer class];
}
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
CAEAGLLayer* eaglLayer = (CAEAGLLayer*) super.layer;
eaglLayer.opaque = YES;
m_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
if (!m_context || ![EAGLContext setCurrentContext:m_context]) {
[self release];
return nil;
}
// Initialization code
GLuint framebuffer, renderbuffer;
glGenFramebuffersOES(1, &framebuffer);
glGenRenderbuffersOES(1, &renderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, renderbuffer);
[m_context
renderbufferStorage:GL_RENDERBUFFER_OES
fromDrawable:eaglLayer];
glFramebufferRenderbufferOES(
GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES,
GL_RENDERBUFFER_OES, renderbuffer);
glViewport(0, 0, CGRectGetWidth(frame), CGRectGetHeight(frame));
[self drawWiew];
}
return self;
}
-(void)drawWiew {
glClearColor(0.5f, 0.5f, 0.5f, 1);
glClear(GL_COLOR_BUFFER_BIT);
[m_context presentRenderbuffer:GL_RENDERBUFFER_OES];
NSLog(#"drawView called");
}
-(void)dealloc {
if ([EAGLContext currentContext] == m_context)
[EAGLContext setCurrentContext:nil];
[m_context release];
[super dealloc];
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
#end
HellowArrowAppDelegate.h:
#import <UIKit/UIKit.h>
#import "GLView.h"
#interface HelloArrowAppDelegate : UIResponder <UIApplicationDelegate> {
UIWindow* window;
GLView* view;
}
#property (strong, nonatomic) UIWindow *window;
#end
HellowArrowAppDelegate.mm:
#import "HelloArrowAppDelegate.h"
#implementation HelloArrowAppDelegate
#synthesize window = _window;
- (void)dealloc
{
[_window release];
[super dealloc];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
CGRect screenBounds = [[UIScreen mainScreen] bounds];
_window = [[UIWindow alloc] initWithFrame:screenBounds];
view = [[GLView alloc] initWithFrame:screenBounds];
[_window addSubview:view];
[_window makeKeyWindow];
// self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// // Override point for customization after application launch.
// self.window.backgroundColor = [UIColor whiteColor];
// [self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
/*
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
*/
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
/*
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
*/
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
/*
Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
*/
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
/*
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
*/
}
- (void)applicationWillTerminate:(UIApplication *)application
{
/*
Called when the application is about to terminate.
Save data if appropriate.
See also applicationDidEnterBackground:.
*/
}
#end

OpenGL screens can turn black depending upon the version of the OS used, as well as the size of the screen window being drawn into. For instance, code that runs fine on 4.0, 4.1, and 4.3 can show up black in 4.2. Or if you double the size of the OpenGL window it works. Sometimes the firmware gets in the way--try messing around with using a newer version of the OS, and see if it works better.

Related

Overlay an image when app is inactive

I'm using these code to
1) overlay an image when the app is inactive (double tap the home button twice).
2) Remove the image when the app is active (reopen the app)
In appdelegate.h file:
#property (nonatomic, strong) UIImageView *splashScreenImageView;
In appdelegate.m file:
- (void)applicationWillResignActive:(UIApplication *)application
{
UIImage *splashScreenImage = [UIImage imageNamed:#"BackgroundScreenCaching"];
_splashScreenImageView = [[UIImageView alloc] initWithImage:splashScreenImage];
[self.window addSubview:_splashScreenImageView];
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
if(_splashScreenImageView != nil) {
[_splashScreenImageView removeFromSuperview];
_splashScreenImageView = nil;
}
}
Problem:
However, SOMETIME when pressing the home button twice, the iOS still caches the app screen with sensitive information instead of the overlay image in iOS 11. Tested no issue in iOS10.
Updated
Issue still persist after changing to this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
BOOL result = [super application:application didFinishLaunchingWithOptions:launchOptions];
...
UIImage *splashScreenImage = [UIImage imageNamed:#"BackgroundScreenCaching"];
_splashScreenImageView = [[UIImageView alloc] initWithImage:splashScreenImage];
[_splashScreenImageView setFrame:self.window.bounds];
return result;
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
if(_splashScreenImageView != nil) {
[_splashScreenImageView removeFromSuperview];
}
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
[self.window addSubview:_splashScreenImageView];
}
I found a tricky way and it works with iOS 11 or iOS 10.
In Appdelegate.m file:
#implementation AppDelegate {
UIImageView *splashScreenImageView;
UIViewController *viewController;
}
Add this code in didFinishLaunchingWithOptions to set image and update frame
splashScreenImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
splashScreenImageView.image = [UIImage imageNamed:#"BackgroundScreenCaching"];
Implement this method for getting topmost view controller
- (UIViewController *)topViewController{
return [self topViewController:[UIApplicationsharedApplication].keyWindow.rootViewController];
}
- (UIViewController *)topViewController:(UIViewController *)rootViewController
{
if (rootViewController.presentedViewController == nil) {
return rootViewController;
}
if ([rootViewController.presentedViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *navigationController = (UINavigationController *)rootViewController.presentedViewController;
UIViewController *lastViewController = [[navigationController viewControllers] lastObject];
return [self topViewController:lastViewController];
}
UIViewController *presentedViewController = (UIViewController *)rootViewController.presentedViewController;
return [self topViewController:presentedViewController];
}
Now in applicationWillResignActive method first get the top viewController and set splashScreenImageView on that view as subview
- (void)applicationWillResignActive:(UIApplication *)application {
viewController = [self topViewController];
[viewController.view addSubview:splashScreenImageView];
}
Finally in applicationDidBecomeActive when app open first remove the overlay image and open app
- (void)applicationDidBecomeActive:(UIApplication *)application {
[splashScreenImageView removeFromSuperview];
}
This tricks will work.
Your code should work fine ,
May be your app didn't get time to alloc your imageView on time when applicationWillResignActive called
and you are re-creating object every time . with [UIImageView alloc] initWithImage
So my suggestion is put this code in didFinishLaunching
UIImage *splashScreenImage = [UIImage imageNamed:#"BackgroundScreenCaching"];
_splashScreenImageView = [[UIImageView alloc] initWithImage:splashScreenImage];
and just add subview on UIWindow and remove it when applicationDidBecomeActive
Also bring _splashScreenImageView to front !!
Hope it may solve your problem
Good Luck
UPDATE
to add in main queue
dispatch_async(dispatch_get_main_queue(), ^{
[self.window addSubview:_splashScreenImageView];
[self.window bringSubviewToFront:_splashScreenImageView];
});
to remove in main queue
dispatch_async(dispatch_get_main_queue(), ^{
[_splashScreenImageView removeFromSuperview];
});
UPDATE 2
according to https://developer.apple.com/library/content/qa/qa1838/_index.html
and
https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/StrategiesforHandlingAppStateTransitions/StrategiesforHandlingAppStateTransitions.html
Prepare for the App Snapshot
Shortly after an app delegate’s applicationDidEnterBackground: method returns, the system takes a snapshot of the app’s windows. Similarly, when an app is woken up to perform background tasks, the system may take a new snapshot to reflect any relevant changes. For example, when an app is woken to process downloaded items, the system takes a new snapshot so that can reflect any changes caused by the incorporation of the items. The system uses these snapshot images in the multitasking UI to show the state of your app.
If you make changes to your views upon entering the background, you can call the snapshotViewAfterScreenUpdates: method of your main view to force those changes to be rendered. Calling the setNeedsDisplay method on a view is ineffective for snapshots because the snapshot is taken before the next drawing cycle, thus preventing any changes from being rendered. Calling the snapshotViewAfterScreenUpdates: method with a value of YES forces an immediate update to the underlying buffers that the snapshot machinery uses.
Try to present temp view controller applicationDidEnterBackground as done in demo of Apple
I fix your bug like this:
#import "AppDelegate.h"
#interface AppDelegate () {
UIImageView *test ;
}
#end
#implementation AppDelegate
- (void)applicationDidEnterBackground:(UIApplication *)application {
UIImage *splashScreenImage = [UIImage imageNamed:#"ic_target_black"];
test = [[UIImageView alloc] initWithImage:splashScreenImage];
[self.window addSubview:test];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
if (test) {
[test removeFromSuperview];
}
}
#end
Do this two simple steps to set your black image when double click the app and it is in recent apps list. And remove the black image when the application becomes active.
#interface AppDelegate (){
UIImageView *test ;
}
- (void)applicationWillResignActive:(UIApplication *)application {
UIImage *splashScreenImage = [UIImage imageNamed:#"ss.png"];
test = [[UIImageView alloc] initWithImage:splashScreenImage];
[self.window addSubview:test];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
if (test) {
[test removeFromSuperview];
}
}

MobileFirst My migrated iOS project unresponsive if I extend WLAppDelegate, but not if I extend WLCordovaAppDelegate

I've migrated 9 iOS Hybrid apps from MobileFirst 6.3 to MobileFirst 7.1 using MobileFirst Studio. 4 of the apps work fine. But the other 5, the UI is unresponsive to clicks. As part of the automated migration process, the headers of these 5 apps (only) were changed to reference the new WLAppDelegate interface. Strangely I've noticed that if I switch my AppName.h file from extending WLAppDelegate back to extending the original WLCordovaAppDelegate everything works fine. Why? I'd love to move off this deprecated code to your new WLAppDelegate interface.
My header and .m file match the defaults generated by MobileFirst Studio 7.1 when you request a new iOS app so it must be something else.
Here's my non-working .h and .m file
//
// MyAppDelegate.h
//
//
#import <IBMMobileFirstPlatformFoundationHybrid/IBMMobileFirstPlatformFoundationHybrid.h>
#interface MyAppDelegate : WLAppDelegate <WLInitWebFrameworkDelegate> {
}
#end
//
// MyAppDelegate.m
// IssuesReturns
//
//
#import "IssuesReturns.h"
#import <IBMMobileFirstPlatformFoundationHybrid/IBMMobileFirstPlatformFoundationHybrid.h>
#import "CDVMainViewController.h"
#implementation MyAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
BOOL result = [super application:application didFinishLaunchingWithOptions:launchOptions];
// A root view controller must be created in application:didFinishLaunchingWithOptions:
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UIViewController* rootViewController = [[UIViewController alloc] init];
[self.window setRootViewController:rootViewController];
[self.window makeKeyAndVisible];
[[WL sharedInstance] showSplashScreen];
// By default splash screen will be automatically hidden once Worklight JavaScript framework is complete.
// To override this behaviour set autoHideSplash property in initOptions.js to false and use WL.App.hideSplashScreen() API.
[[WL sharedInstance] initializeWebFrameworkWithDelegate:self];
return result;
}
// This method is called after the WL web framework initialization is complete and web resources are ready to be used.
-(void)wlInitWebFrameworkDidCompleteWithResult:(WLWebFrameworkInitResult *)result
{
if ([result statusCode] == WLWebFrameworkInitResultSuccess) {
[self wlInitDidCompleteSuccessfully];
} else {
[self wlInitDidFailWithResult:result];
}
}
-(void)wlInitDidCompleteSuccessfully
{
UIViewController* rootViewController = self.window.rootViewController;
// Create a Cordova View Controller
CDVMainViewController* cordovaViewController = [[CDVMainViewController alloc] init] ;
cordovaViewController.startPage = [[WL sharedInstance] mainHtmlFilePath];
// Adjust the Cordova view controller view frame to match its parent view bounds
cordovaViewController.view.frame = rootViewController.view.bounds;
// Display the Cordova view
[rootViewController addChildViewController:cordovaViewController];
[rootViewController.view addSubview:cordovaViewController.view];
[cordovaViewController didMoveToParentViewController:rootViewController];
}
-(void)wlInitDidFailWithResult:(WLWebFrameworkInitResult *)result
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"ERROR"
message:[result message]
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
#end
WLCordovaAppDelegate is a deprecated compatibility API to allow easier migration of pre v6.2 apps to 6.2+ apps. It can be used but the recommendation is to use WLAppDelegate.

unrecognized selector sent to instance | Objective C

The app crash on startup and I have this error in the console :
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[Chartboost showInterstitial]:
unrecognized selector sent to instance 0x7f844c9b74e0'
my code is :
#import "cocos2d.h"
#import "AppDelegate.h"
#import "IntroLayer.h"
#import "AppSpecificValues.h"
#import <RevMobAds/RevMobAds.h>
#import <Chartboost/Chartboost.h>
#implementation AppController
#synthesize gameCenterManager=gameCenterManager_, currentLeaderBoard=currentLeaderBoard_;
#synthesize window=window_, navController=navController_, director=director_;
#synthesize cb;
#synthesize nScore;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Create the main window
window_ = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Create an CCGLView with a RGB565 color buffer, and a depth buffer of 0-bits
CCGLView *glView = [CCGLView viewWithFrame:[window_ bounds]
pixelFormat:kEAGLColorFormatRGB565 //kEAGLColorFormatRGBA8
depthFormat:0 //GL_DEPTH_COMPONENT24_OES
preserveBackbuffer:NO
sharegroup:nil
multiSampling:NO
numberOfSamples:0];
director_ = (CCDirectorIOS*) [CCDirector sharedDirector];
director_.wantsFullScreenLayout = YES;
// Display FSP and SPF
// [director_ setDisplayStats:YES];
// set FPS at 60
[director_ setAnimationInterval:1.0/60];
// attach the openglView to the director
[director_ setView:glView];
// for rotation and other messages
[director_ setDelegate:self];
// 2D projection
[director_ setProjection:kCCDirectorProjection2D];
// [director setProjection:kCCDirectorProjection3D];
// Enables High Res mode (Retina Display) on iPhone 4 and maintains low res on all other devices
if( ! [director_ enableRetinaDisplay:YES] )
CCLOG(#"Retina Display Not supported");
// Default texture format for PNG/BMP/TIFF/JPEG/GIF images
// It can be RGBA8888, RGBA4444, RGB5_A1, RGB565
// You can change anytime.
[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];
// If the 1st suffix is not found and if fallback is enabled then fallback suffixes are going to searched. If none is found, it will try with the name without suffix.
// On iPad HD : "-ipadhd", "-ipad", "-hd"
// On iPad : "-ipad", "-hd"
// On iPhone HD: "-hd"
CCFileUtils *sharedFileUtils = [CCFileUtils sharedFileUtils];
[sharedFileUtils setEnableFallbackSuffixes:NO]; // Default: NO. No fallback suffixes are going to be used
[sharedFileUtils setiPhoneRetinaDisplaySuffix:#"-hd"]; // Default on iPhone RetinaDisplay is "-hd"
[sharedFileUtils setiPadSuffix:#"-ipad"]; // Default on iPad is "ipad"
[sharedFileUtils setiPadRetinaDisplaySuffix:#"-ipad-hd"]; // Default on iPad RetinaDisplay is "-ipadhd"
// Assume that PVR images have premultiplied alpha
[CCTexture2D PVRImagesHavePremultipliedAlpha:YES];
self.nScore = 0;
//Revmobs
[RevMobAds startSessionWithAppID:[[NSBundle mainBundle] objectForInfoDictionaryKey:#"RevMobAPI"]];
// and add the scene to the stack. The director will run it when it automatically when the view is displayed.
[director_ pushScene: [IntroLayer scene]];
[self initGameCenter];
// Create a Navigation Controller with the Director
navController_ = [[UINavigationController alloc] initWithRootViewController:director_];
navController_.navigationBarHidden = YES;
// set the Navigation Controller as the root view controller
// [window_ addSubview:navController_.view]; // Generates flicker.
[window_ setRootViewController:navController_];
// make main window visible
[window_ makeKeyAndVisible];
return YES;
}
-(void) lunchRevmobADLink
{
[[RevMobAds session] openAdLinkWithDelegate:self];
}
- (void) setUpRevMob {
[[RevMobAds session] showFullscreen];
}
-(void) launchChartboost
{
// Initialize the Chartboost library
[Chartboost startWithAppId:#"53be6ed01873dc9741aafa"
appSignature:#"fcd1715a73c97b22c5ad557323a59d7348476"
delegate:self];
// Begin a user session. This should be done once per boot
[cb startSession];
[cb cacheInterstitial];
[cb cacheMoreApps];
}
-(void) showChartboostInterestitial
{
// Show an interstitial
[[Chartboost sharedChartboost] showInterstitial];
}
-(void) showChartboostMoreApps
{
[[Chartboost sharedChartboost] showMoreApps];
}
// Supported orientations: Landscape. Customize it for your own needs
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return UIInterfaceOrientationIsPortrait(interfaceOrientation);
}
// getting a call, pause the game
-(void) applicationWillResignActive:(UIApplication *)application
{
if( [navController_ visibleViewController] == director_ )
[director_ pause];
}
// call got rejected
-(void) applicationDidBecomeActive:(UIApplication *)application
{
if( [navController_ visibleViewController] == director_ )
[director_ resume];
[self launchChartboost];
#ifdef FREE_VERSION
[self showChartboostInterestitial];
[self setUpRevMob];
[self hideAdBanner:YES];
#endif
}
and other code.
I tried lot of things! So I ask you now, How I can resolve this???
Thank's in advance!
According to Chartboost documentation you are not trying to show interstitial the right way :
To show a static or interstitial video ad:
// Show interstitial at location HomeScreen. See Chartboost.h for available location options.
[Chartboost showInterstitial:CBLocationHomeScreen];
The way you are doing it has been removed in their SDK 5.x
All references to [Chartboost sharedChartboost] are now changed to
Chartboost:
[[Chartboost sharedChartboost] showInterstitial:CBLocationHomeScreen]; is now [Chartboost
showInterstitial:CBLocationHomeScreen];
you are calling showInterstitial on an instance although it is a class method. it should be something like [Chartboost showInterstitial...

MMDrawerController unrecognized selector

I'm trying to setup a siderbar navigation menu for my app. I'm using the MMDrawerController lib, but I'm running into an issue. I've added a button and use these methods to call the sidebar:
-(void)setupLeftMenuButton{
MMDrawerBarButtonItem * leftDrawerButton = [[MMDrawerBarButtonItem alloc] initWithTarget:self action:#selector(leftDrawerButtonPress:)];
[self.navigationItem setLeftBarButtonItem:leftDrawerButton animated:YES];
}
-(void)leftDrawerButtonPress:(id)sender{
[self.mm_drawerController toggleDrawerSide:MMDrawerSideLeft animated:YES completion:nil];
}
I'm using a Navigation Controller with a View Controller attached in which I'm calling this method. This viewcontroller is called ViewController2.
Whenever I press the button to pull out the sidemenu, it crashes and returns this error:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ViewController2 mm_drawerController]: unrecognized selector sent to instance 0x835b440'
What am I doing wrong?
edit:
AppDelegate.h
#import "AppDelegate.h"
#import "MMDrawerController.h"
#import "ViewController2.h"
#import "MMLeftSideDrawerViewController.h"
#import "MMRightSideDrawerViewController.h"
#import "MMDrawerVisualState.h"
#import "MMDrawerVisualStateManager.h"
#import <QuartzCore/QuartzCore.h>
#interface AppDelegate ()
#property (nonatomic,strong) MMDrawerController * drawerController;
#end
#implementation AppDelegate
-(BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
UIViewController * leftSideDrawerViewController = [[MMLeftSideDrawerViewController alloc] init];
UIViewController * centerViewController = [[ViewController2 alloc] init]; // MAYBE SOMETHING WRONG HERE?
UIViewController * rightSideDrawerViewController = [[MMRightSideDrawerViewController alloc] init];
UINavigationController * navigationController = [[UINavigationController alloc] initWithRootViewController:centerViewController];
[navigationController setRestorationIdentifier:#"MMCenterNavigationControllerRestorationKey"];
self.drawerController = [[MMDrawerController alloc]
initWithCenterViewController:navigationController
leftDrawerViewController:leftSideDrawerViewController
rightDrawerViewController:rightSideDrawerViewController];
[self.drawerController setRestorationIdentifier:#"MMDrawer"];
[self.drawerController setMaximumRightDrawerWidth:200.0];
[self.drawerController setOpenDrawerGestureModeMask:MMOpenDrawerGestureModeAll];
[self.drawerController setCloseDrawerGestureModeMask:MMCloseDrawerGestureModeAll];
[self.drawerController
setDrawerVisualStateBlock:^(MMDrawerController *drawerController, MMDrawerSide drawerSide, CGFloat percentVisible) {
MMDrawerControllerDrawerVisualStateBlock block;
block = [[MMDrawerVisualStateManager sharedManager]
drawerVisualStateBlockForDrawerSide:drawerSide];
if(block){
block(drawerController, drawerSide, percentVisible);
}
}];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window setRootViewController:self.drawerController];
return YES;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
- (BOOL)application:(UIApplication *)application shouldSaveApplicationState:(NSCoder *)coder{
return YES;
}
- (BOOL)application:(UIApplication *)application shouldRestoreApplicationState:(NSCoder *)coder{
return YES;
}
- (UIViewController *)application:(UIApplication *)application viewControllerWithRestorationIdentifierPath:(NSArray *)identifierComponents coder:(NSCoder *)coder
{
NSString * key = [identifierComponents lastObject];
if([key isEqualToString:#"MMDrawer"]){
return self.window.rootViewController;
}
else if ([key isEqualToString:#"MMCenterNavigationControllerRestorationKey"]) {
return ((MMDrawerController *)self.window.rootViewController).centerViewController;
}
else if ([key isEqualToString:#"MMLeftSideDrawerController"]){
return ((MMDrawerController *)self.window.rootViewController).leftDrawerViewController;
}
else if ([key isEqualToString:#"MMRightSideDrawerController"]){
return ((MMDrawerController *)self.window.rootViewController).rightDrawerViewController;
}
return nil;
}
#end
Take a look at the example have you tried something like in case you are using navigation
(or swapping view in case you are not)
[(UINavigationController*)self.mm_drawerController.centerViewController pushViewController: animated:YES];

open a new view inside app delegate

the app delegate.h file is as follows
#import <UIKit/UIKit.h>
#class AFAViewController;
#class OpenInChromeController;
#class AFABarcodeScanner;
#interface AFAAppDelegate : NSObject <UIApplicationDelegate,UIAlertViewDelegate>
{
OpenInChromeController *openInChromeController_;
AFABarcodeScanner *bs;
}
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic)AFAViewController *viewController;
#property(strong,nonatomic)AFABarcodeScanner *bs;
#end
the app delegate.m file is as follows
#import "AFAAppDelegate.h"
#import "AFAViewController.h"
#import "OpenInChromeController.h"
#import "AFABarcodeScanner.h"
#implementation AFAAppDelegate
#synthesize bs;
#synthesize window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
{
self.viewController = [[AFAViewController alloc] initWithNibName:#"AFAViewController_iPhone" bundle:nil];
}
else
{
self.viewController = [[AFAViewController alloc] initWithNibName:#"AFAViewController_iPad" bundle:nil];
}
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:
#"itms-apps://itunes.apple.com/us/app/chrome/id535886823"]];
}
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
UIAlertView *alertView;
alertView = [[UIAlertView alloc] initWithTitle:#"Error" message:#"inside open url" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
AFABarcodeScanner *vc = [[AFABarcodeScanner alloc] initWithNibName:#"AFABarcodeScanner" bundle:nil];
[self.view addSubview:vc.view];
return YES;
}
#end
i would like open the new view inside the custom url function. When the request is obtained from external web page the view inside the application delegate must be opened.
There are couple of ways to achieve it:
First: AppDelegate has a property window. A window is a view, so you can do
[self.window addSubview:newView];
Second: a view controller can reach the window without dealing with the app delegate.
[controller.view addSubview:overlayView];
Get the instance of the AFAViewController(self.viewController) and add the subview to this view or else present AFABarcodeScanner as model if possible

Resources