I tried to integrate the JASidePanel in my app. Below is my code for initialising JSSidePanel controller.
- (void)viewDidLoad {
[super viewDidLoad];
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main"
bundle: nil];
UIWindow *window= [UIApplication sharedApplication].keyWindow;
self.viewController = [[JASidePanelController alloc] init];
self.viewController.shouldDelegateAutorotateToVisiblePanel = NO;
self.viewController.leftPanel = [mainStoryboard instantiateViewControllerWithIdentifier:#"BBWSideMenuViewController"];
self.viewController.centerPanel = [self.navigationController.viewControllers lastObject];
window.rootViewController = self.navigationController;
[window makeKeyAndVisible];
}
Button Action method,
- (IBAction)openSideMenu:(id)sender {
[self.viewController showLeftPanelAnimated:YES];
}
When I'm pressing button to open side menu, entire screen is getting black. How may i fix this?. Any Help will be much appreciated.
Related
I have a react native project where I am trying to present a external view controller using React Native iOS Native Modules.
In my AppDelegate, I have instantiated a viewController using storyboard and populating it with react createRootViewWithBridge view.
AppDelegate.mm
UIView *rootView = [self.reactDelegate createRootViewWithBridge:bridge moduleName:#"main" initialProperties:nil];
rootView.backgroundColor = [UIColor whiteColor];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *reactViewController = [storyboard instantiateViewControllerWithIdentifier: #"ReactViewController"];
reactViewController.view = rootView;
UINavigationController *navController = (UINavigationController*)[storyboard
instantiateViewControllerWithIdentifier: #"UINavigationController"];
[navController pushViewController:viewController animated:YES];
self.navController = navController;
self.window.rootViewController = navController;
[self.window makeKeyAndVisible]; [super application:application didFinishLaunchingWithOptions:launchOptions];
return YES;
I have a IOS native module that I call using from my react Side:
Homescreen.tsx
SdkModule.openPendingAuthorization(
RAS_USER_ID,
RAS_CLIENT_ID,
RAS_CLIENT_SECRET,
RAS_URL
)
And then in my native module method, I am pushing the viewcontroller into the navigation controller.
RCTSdkModule.m
RCT_EXPORT_METHOD(openPendingAuthorization:(NSString *)userId
clientId:(NSString *)clientId
clientSecret:(NSString *)clientSecret
url:(NSString *)url)
{
Data *obj=[Data getInstance];
obj.userId = userId;
obj.clientId = clientId;
obj.clientSecret = clientSecret;
obj.url = url;
dispatch_async(dispatch_get_main_queue(), ^{
UIApplication *app = [UIApplication sharedApplication];
UINavigationController *nav = (UINavigationController *) app.delegate.window.rootViewController;
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier: #"SdkViewController"];
[nav pushViewController:viewController animated:YES];
});
}
And then, I am able to run the SDK code in viewcontroller related to SDK:
SdkViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
// SDK Related Code
}
My code runs fine when I run it as DEBUG build in XCode. But, if I switch to Release build or, Create ipa using eas build, it gives me the following error.
`unrecognized selector sent to instance-pushviewcontrolleranimated
It seems that, in [nav pushViewController:viewController animated:YES] , the nav is a viewController, not a UINavigationController. But it does not give the error in Debug mode.
App is in Background
Push notification is received and clicked
App will open and be redirect to the SecondViewController and the back button is clicked
When click to the back button from SecondViewController and back to FirstViewController the "Menu" loss the reference from MenuViewController
Push notification is received and clicked
App will open and be redirect to the SecondViewController and the back button is clicked
When click to the back button from SecondViewController and back to FirstViewController the "Menu" loss the reference from MenuViewController
My Code:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
if (application.applicationState == UIApplicationStateActive) {
.......
} else {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UINavigationController *navigationController=[[UINavigationController alloc] init];
self.window.rootViewController = nil;
self.window.rootViewController = navigationController;
MenuViewController *menuViewController = [storyboard instantiateViewControllerWithIdentifier:#"MenuViewController"];
[navigationController pushViewController:menuViewController animated:NO];
HomeViewController *homeViewController = [storyboard instantiateViewControllerWithIdentifier:#"HomeViewController"];
[navigationController pushViewController:homeViewController animated:NO];
AllNewsNotificationViewController *allNewsNotificationViewController = [storyboard instantiateViewControllerWithIdentifier:#"AllNewsNotificationViewController"];
[navigationController pushViewController:allNewsNotificationViewController animated:YES];
[self.window makeKeyAndVisible];
}
My MenuViewController impl:
#implementation MenuViewController
- (id)init {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
self = [storyboard instantiateViewControllerWithIdentifier:#"MenuViewController"];
if (!self) {
return self;
}
self.navigationController = [[UINavigationController alloc] initWithRootViewController:self.homeViewController];
NSDictionary *options = #{
PKRevealControllerRecognizesPanningOnFrontViewKey : #YES,
PKRevealControllerDisablesFrontViewInteractionKey : #NO
};
self.revealController = [SubviewPKRevealViewController revealControllerWithFrontViewController:self.navigationController leftViewController:self options:options];
self.revealController.revealDelegate = self.homeViewController;
// The target view controller must implement this method
self.navBarGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self.homeViewController action:#selector(menuPan:)];
[self.navigationController.navigationBar addGestureRecognizer:self.navBarGesture];
self.view.backgroundColor = [[Configurations sharedInstance] menuBackgroundColor];
_topView.backgroundColor = [[Configurations sharedInstance] navegationbarBackgroundColor];
return self;
}
Menu shortcut (button) from MenuViewController lost the reference and doesn't works.
I need to show a ViewController from the appDelegate every time the app comes from the background in the applicationDidEnterBackground method.
The *securityCheck prompts the user for a passcode very much like the normal passcode in iOS. Once the passcode is validated I call dimissViewControllerAnimated inside the securityCheck and I am left with my blank UINavigationController, since the view was presented from the appDelegate I have no record of who presented the view, so I can't popToRootViewController.
My question is how can I properly dismiss the SecurityCheckViewController so that it shows the ViewController which the user was on before the app entered the background.
Here's my code:
This method is called inside AppDelegate.m
- (void)securityCheck {
SecurityCheckViewController *securityCheck = [[SecurityCheckViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:securityCheck];
[securityCheck presentedByAppDelegate:YES];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window setRootViewController:navigationController];
[self.window makeKeyAndVisible];
}
Then inside the SecurityCheckViewController.m I have
- (void)unlockWasSuccessfulForPadLockScreenViewController:(ABPadLockScreenViewController *)padLockScreenViewController {
[self.appDelegate securityCheckDone];
[padLockScreenViewController dismissViewControllerAnimated:YES completion:nil];
NSLog(#"Sucsessfull Unlock");I'm
}
Present
- (void)securityCheck {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
SecurityCheckViewController *securityCheck = [storyboard instantiateViewControllerWithIdentifier:#"securityCheckView"];
[self.window.rootViewController presentViewController:securityCheck animated:NO completion:nil];
}
Dismiss
[self dismissViewControllerAnimated:YES completion:nil];
You can call this from application:didFinishLaunchingWithOptions
NOTE: All the storyBoard "initialViewControllers" tick box on the property inspector is turned off
UIStoryboard *storyboard =
[UIStoryboard storyboardWithName:#"Registration" bundle:nil];
RegisterViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"RegisterViewController"];
//this is key else you get a black screen
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
So in my App.Delegate I'm doing this -
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.loginViewController = [[LoginViewController alloc] initWithNibName:#"LoginView" bundle:[NSBundle mainBundle]];
UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController: self.loginViewController];
self.window.rootViewController = navigation;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
and in my login controller I'm doing this -
- (IBAction)login:(UIButton *)sender {
NSString *username = self.userName.text;
NSString *password = self.password.text;
[AccountUtils emailLogin:username password:password useCookie:true callback:^(NSDictionary *loginResponseJSON){
if([loginResponseJSON count] != 0){
[self performSelectorOnMainThread:#selector(displaySearchController) withObject:nil waitUntilDone:YES];
// [self performSelectorOnMainThread:#selector(switchState) withObject:nil waitUntilDone:YES];
} else {
//incorrect entry info view here.
}
}];
}
- (void) displaySearchController {
SearchViewController *searchViewController = [[SearchViewController alloc] initWithNibName:#"SearchView" bundle:[NSBundle mainBundle]];
UINavigationController *navigator = self.navigationController;
[navigator popViewControllerAnimated: YES];
[navigator pushViewController: searchViewController animated:YES];
}
If I correctly login, I go to the second controller's view, but at the top I'm still allowed to go 'back' to the login page. I don't want that to happen and I thought this case would be taken care off by the popViewControllerAnimated line. How do I make it so that when I login, I am not allowed to go back to the login page?(in other words, I guess pop the login controller off the navigation controller's stack?)
If you want just to remove the loginVC you could set the new navigationController as the rootViewController of the AppDelegate after the user has logged in. So you could move the displaySearchController method in the AppDelegate and call this method (from the loginVC) after the user has logged in:
-(void)displaySearchController{
SearchViewController *searchViewController = [[SearchViewController alloc] initWithNibName:#"SearchView" bundle:[NSBundle mainBundle]];
UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController: searchViewController];
self.window.rootViewController=navigation;
}
Otherwise, if you really want the push animation, you can remove the loginVC from the navigationController viewControllers stack in the viewDidAppear of SearchDispalyController:
-(void)viewDidAppear:(BOOL)animated{
NSMutableArray *stackVCs=[self.navigationController.viewControllers mutableCopy];
int idx=[stackVCs indexOfObject:self];
//this remove the previous viewcontroller from the stack
[stackVCs removeObjectAtIndex:idx-1];
self.navigationController.viewControllers=stackVCs;
[super viewDidAppear:animated];
}
Also in the loginVC just before push the searchVC you should call this to hide the back button:
[navigation.navigationItem setHidesBackButton:YES];
You don't want to use a UINavigationController with the LoginViewController and you don't want to push the SearchViewController. Instead, use a UINavigationController with SearchViewController and when you display it, make it the rootViewController.
Do this to achieve what you want.
Move the displaySearchController method to your AppDelegate.m file
Do declare the displaySearchController method in AppDelegate.h file
Now Define the displaySearchController method in AppDelegate.m file as :
- (void) displaySearchController {
SearchViewController *searchViewController = [[SearchViewController alloc] initWithNibName:#"SearchView" bundle:[NSBundle mainBundle]];
UINavigationController *navigator = [[UINavigationController alloc]initWithRootViewController:searchViewController];
self.window.rootViewController = navigator;
}
Call a new local method showNewViewController from your loginController as :
[self performSelectorOnMainThread:#selector(showNewViewController) withObject:nil waitUntilDone:YES];
Now define showNewViewController in your loginController.m file as
-(void)showNewViewController {
AppDelegate *appDele = [UIApplication sharedApplication].delegate;
[appDele displaySearchController];
}
Don't forget to import the AppDelegate.h file to your loginController.m
This will certainly help you.
This is what i am doing in my application:
in my appDelegate.m file ,
//Four Views
#synthesize fvc;
#synthesize svc;
#synthesize tvc;
#synthesize pvc;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
NSString *name1,*name2,*name3;
name1 = NSLocalizedString(#"home", nil);
name2 = NSLocalizedString(#"quote", nil);
name3 = NSLocalizedString(#"ship", nil);
UITabBarController *tabBar = [[UITabBarController alloc] init];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle: nil];
//[application setStatusBarStyle:UIStatusBarStyleBlackTranslucent];
tvc = [storyboard instantiateViewControllerWithIdentifier:#"thirdview"];
fvc = [storyboard instantiateViewControllerWithIdentifier:#"firstview"];
svc = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
pvc =[storyboard instantiateViewControllerWithIdentifier:#"PayViewController"];
fvc.tabBarItem.title = name1;
fvc.tabBarItem.image = [UIImage imageNamed:#"home.png"];
fvc.tabBarItem.titlePositionAdjustment = UIOffsetMake(2.0, 0);
tvc.tabBarItem.title = name2;
tvc.tabBarItem.image = [UIImage imageNamed:#"ping.png"];
tvc.tabBarItem.titlePositionAdjustment = UIOffsetMake(0, 2.0);
svc.tabBarItem.title = name3;
svc.tabBarItem.image = [UIImage imageNamed:#"zoom.png"];
svc.tabBarItem.titlePositionAdjustment = UIOffsetMake(-5.0, 0);
NSLog(#"appdelegate %# and %#",svc,svc.title);
tabBar.viewControllers = [NSArray arrayWithObjects:fvc,svc,tvc,nil];
// the below line does not allow [self.navigationController pushViewController:svNew animated:YES]; to function
self.window.rootViewController = tabBar;
// Override point for customization after application launch.
return YES;
In my fvc view im performing change view operation in okPressed method:
- (IBAction)okPressed:(id)sender {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle: nil];
SecondViewController *svNew = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
[self.navigationController pushViewController:svNew animated:YES];
}
When i comment the code in the appdelegate method the switching between the views thru the okPressed method is executed successfully. But when I uncomment the appDelegate method it does not perform switching. What i found out was , the code in appdelegate method "self.window.rootViewController = tabBar;" is the culprit. Can anyone guide me on this.
I think you should embed your UITabBarController in a Navigation Controller to make it work:
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:tabBar];
and then
self.window.rootViewController = navController;
Otherwise you can't push anything since you probably got no UINavigationController to push things to!