SWRevealViewController after a login view - ios

I have an app that have a login view and then after the login is successes I want to have a view with a side menu.
I am using SWRevealViewController to make the slide menu.
But the problem as I said is the login view will be the first view not the SWRevealViewController.
I tried to do the following inside prepareForSegue method.
SWRevealViewController *revealViewController;
[revealViewController initWithRearViewController: [self.storyboard instantiateViewControllerWithIdentifier:#"MenuTableViewCell"]frontViewController:[self.storyboard instantiateViewControllerWithIdentifier:#"HomeViewController"]];
this is not working. That's the only code I have inside prepareForSegue method, I deleted the if statement because I only have one segue inside the loginview so I figured I don't need the IF.
Should I delete the SWRevealViewController from the storyboard? or make the segue from the login view to SWRevealViewController
I don't know what to do.
There's no explanation for situation for using SWRevealViewController inside the views not the first view.
I am building this app for iOS for objective c for iPhone.
Please help.
Thanks.

You should do your storyboard hierarchy like this.
Drag a ViewController and change a class to SWRevealViewController.
Drag a ViewController Embedded in NavigationController. Change class name to LoginViewController.
Change your NavigationController's storyboard ID to "LoginNavigationController".
Assign new custom segue named sw_front from SWRevealViewController to NavigationController and change class of segue to SWRevealViewControllerSegueSetController.
Drag a controller having TableView as a subView which is your MenuViewController for Sidebar.
Assign new custom segue named sw_rear from SWRevealViewController to MenuViewController and change class of segue to SWRevealViewControllerSegueSetController.
Now drag a ViewController named HomeViewController embedded in NavigationController and assign a custom segue with identifier "Home" and class with SWRevealViewControllerSeguePushController.
Change storyboard ID of NavigationController to "HomeNavigationController".
This should be the setup in your storyboard.
Now here is the coding part:
In SWRevealViewController.m
- (void)viewDidLoad{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(userSignedInSuccessfully) name:kUserSignedInNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(userSignOutSuccessfully) name:kUserSignedOutNotification object:nil];
// this flag should be maintained in user defaults
if(iSUserSignedIn){
//Show Home page if user is already signed in
[self showHomeScreen];
}
}
#pragma mark - Show Home screen
-(void)showHomeScreen
{
UINavigationController *navigation = [[UIStoryboard storyboardWithName:kStoryboardName bundle:nil] instantiateViewControllerWithIdentifier:#"HomeNavigationController"];
[self setFrontViewController:navigation];
[self setFrontViewPosition:FrontViewPositionLeft];
}
-(void)showLoginScreen{
UINavigationController *navigation = (UINavigationController *)[[UIStoryboard storyboardWithName:kStoryboardName bundle:nil] instantiateViewControllerWithIdentifier:#"LoginNavigationController"];
[self setFrontViewController:navigation];
[self setFrontViewPosition:FrontViewPositionLeft];
}
Now when user signed first save flag iSUserSignedIn in user defaults and post this notification.
//Post notification for successful sign in
[[NSNotificationCenter defaultCenter] postNotificationName:kUserSignedInNotification object:nil];
When user signed out set flag iSUserSignedIn to nil and post this notification.
//Post notification for successful sign out
[[NSNotificationCenter defaultCenter] postNotificationName:kUserSignedOutNotification object:nil];

Related

How to dismiss multiple view controllers which have been presented not pushed?

Scenario:
I need to show 3 or more popups one after the other on button click in each popup. I have created a different viewcontroller and xib files for each popup. So for displaying each popup I have used presentViewController instead of pushViewController.
That is, I have used this:
[self presentPopupViewController:searchPopUpView animationType:0];
instead of
[self.navigationController pushViewController:searchPopUpView animated:YES];
For dismissing a popup, the following code has been written:
[self dismissPopupViewControllerWithanimationType:0];
Issue:
The popups are displaying perfectly, but the background gets darker and darker whenever a popup shows up. After all popups have been dismissed I have to finally click on the blank screen to remove those darker parts. How to overcome this issue?
I think you are using MJPopupViewController to show pop-up.
If it is so, Then try this.
Suppose there is a controllerA from which you want to show a pop-up controller popupControllerB.
Then in your controllerA add Notifications Observer
Code to write in controllerA :
// Add Notification Observer when your view initialise.
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(dismissPopup) name:#"DISMISS_POPUP" object:nil];
In viewWillDisappear remove the notifications observer
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
This method will be called when you Post-notification from your popupControllerB
-(void)dismissPopup {
[self dismissPopupViewControllerWithanimationType:MJPopupViewAnimationFade];
}
And In popupControllerB, Where you want to dismiss the Pop-up, write this code.
[[NSNotificationCenter defaultCenter] postNotificationName:#"DISMISS_POPUP" object:nil];
Above line of code will call a method written in your controllerA and dismiss the pop-up properly.
If you want to dismiss presented UIViewControllers you can use this code. I have used this approach to dismiss presentedViewControllers. It will dismiss all your presentedViewControllers on your rootViewController.
UIViewController* presVC = self.window.rootViewController;
while (presVC) {
UIViewController* temp = vc.presentingViewController;
if (!temp.presentedViewController) {
[vc dismissViewControllerAnimated:NO completion:^{}];
break;
}
vc = temp;
}

Push next view Pagemenu ios xcode

Hello I am using Page menu in application and i want to push from didSelectRowAtIndexPath in next view in one view which is involed in page menu
i know all way which we use for push and model.if i am using model with custom navigation bar then page menu hide on dismiss model.
Assumed hierarchy:
UINavigation Controller -- UIViewController -- UIPageController
UIPageController (with 2 UIViewController) -- UITableViewController-1 and UITableViewController-2
On didSelectRowAtIndexPath method
UIPageController -- UITableViewController-1 //Selected any one row
Then just push the next view controller onto the current UITableViewController.
Note - Both controller in UIPageController maintain separate life cycle that is independent from each other.
One can not push the viewcontroller in pageView , PageviewController don't have navigation controller .
Solution :
There are two ways to make this possible suggested by Nitin Gohel
set notification for event and Retrieve the notification on main Controller
You can send the information in Notification required in another viewController.
NSDictionary* userInfo = #{#"abc": #"aaa"};
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
[nc postNotificationName:#"One" object:self userInfo:userInfo];
In MainViewController just set the onserver for that notification in viewDidLoad method
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(OneNoti:) name:#"One" object:nil];
}
And perform push from MainViewController:
-(void) OneNoti:(NSNotification*)notification
{
NSDictionary* userInfo = notification.userInfo;
NSNumber* total = (NSNumber*)userInfo[#"total"];
NSLog (#"Successfully received test notification! %i", total.intValue);
NSLog(#"%#",notification.userInfo);
[self performSegueWithIdentifier:#"1_" sender:nil];
}
Set the delegate methods in MainView Controller and call the methods while performing action from page view and push from that Action .
Same like above way .

Dismissing view controllers all at once

I need to go back all the way to the view controller that presented the first navigation controller. However I haven't dismissed multiple controllers before at once, and when I've tried doing so, it doesn't work. It just goes to the first navigation controller instead of all the way to the one before it.
Here is my current code:
[(UINavigationController *)self.presentingViewController popViewControllerAnimated:NO];
[self dismissViewControllerAnimated:YES completion:nil];
I have a view controller which modally presents the first navigation controller. The first navigation controller screen is called Main View Controller. It then pushes to Login View Controller. Login View Controller does presentViewController to MenuViewController (UIViewController).
I need to get from MenuViewController all the way back to the view that presented the first navigation controller. Thanks.
Try this
UIViewController *vc = self;
while (vc.presentingViewController != nil) {
vc = vc.presentingViewController;
}
[vc dismissViewControllerAnimated:YES completion:nil];
One option would be to use NSNotifications.
You can add an observer in your first/root/initial UINavigationController subclass e.g.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(logout:)
name:#"LogoutNotification"
object:nil];
Then in your "logout:" method you have direct control over the initial UINavigationController rather than those further up the hierarchy.
You can then send an NSNotification from anywhere in the app in order to trigger the method.
e.g.
[[NSNotificationCenter defaultCenter] postNotificationName:#"LogoutNotification" object:self];

iOS - Call delegate method on main view from popover inner (pushed) view?

I need to call a delegate method on my main view controller ('showDetails:') from a popover view's pushed view (embedded in navigation controller). This is all from a storyboard setup.
The hierarchy is: Main view -> Popover (menu tableview embedded in navigation controller)->Popover secondary View (pushed onto popover navigation controller)
I know how to setup a delegate on the popover using prepareForSegue, but not on an inner view.
How can I call a delegate method on the main view from an inner (pushed) view of a popover?
Here is how I setup the delegate on a popover main view:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"segueSearchResults"]) {
//Dismiss User Popover
[self dismissUserPopover];
SearchResultsViewController *vc = segue.destinationViewController;
vc.searchDelegate = self;
self.searchPopover = [(UIStoryboardPopoverSegue *)segue popoverController];
self.searchPopover.delegate = self;
}
}
Instead Delegate i prefer "NSNotificationCenter" in your case
Add an observer to your ViewController for some action in uiview
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(receiveActionNotification:)
name:#"someActionNotification"
object:nil];
Post Notification from your pushed View in PopOverController
Post Notification and method in your Viewcontroller will be called
[[NSNotificationCenter defaultCenter] postNotificationName:#"someActionNotification" object:self];
At the end Dont forget to remove Observer.
[[NSNotificationCenter defaultCenter] removeObserver:#"someActionNotification"];
When you need to communicate between two view controllers which are far apart in the VC hierarchy, trying to reference one from the other so you can directly call methods on it doesn't work so well -- there's several levels of indirection in between, and it's very fragile if you change your VC hierarchy later.
Look into notifications (NSNotificationCenter) instead; you can have one VC "broadcast" info for another to respond to, regardless of where they are in your app.

MVC consistency, present a viewController from the model

I have a viewController I've built in storyboard. I also have a NSObject Subclass which acts as my model, which sends and listens for API requests and responses. When a method fires in my model, I want to present a modal View of my viewController from whatever view happens to be visible at the time.
An example would be if my API hears "show this view" I want to show viewController regardless of what view is being shown.
Conceptually, how does one do this?
EDIT: I don't know which view controller will be showing when I want to present my modal viewController. Also, I need to pass params from my model to the modalVC when it's presented.
I would send a notification from the model telling "someone" that some view needs be displayed.
NSDictionary *userInfo = #{ #"TheViewKey": viewToDisplay];
[[NSNoticationCenter defaultCenter] postNotificationName:#"NotificationThatThisViewNeedsToBeDisplayed" object:self userInfo:userInfo];
And then on the delegate (or the active view controller) would register to this notification and handle the display.
// self is the delegate and/or the view controller that will receive the notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(handleViewToDisplay:) name:#"NotificationThatThisViewNeedsToBeDisplayed" object:nil];
If you put in the view controller remember to remove self from the observers when the view is not visible:
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"NotificationThatThisViewNeedsToBeDisplayed"];
This way your model is decoupled from the presentation.
You have the current viewController (any viewController subclass) present the new view using:
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion
EDIT: To find the top view controller, you ask the UITabBarController for the selectedViewController (if you use a tabBarController) to get the 'seed', or start with the window.rootViewController.
Once you are past any tabBarControllers, then you should only have UIViewController subclasses and UINavigationControllers. You can use a loop like this:
- (UIViewController *)frontmostController:(UIViewController *)seed
{
UIViewController *ret;
if([seed isKindOfClass:[UINavigationController class]]) {
ret = [(UINavigationController *)seed topViewController];
} else
if([seed isKindOfClass:[UIViewController class]]) {
ret = seed.presentedViewController;
}
return ret ? [self frontmostController:ret] : seed;
}

Resources