Pass object to SASlideMenuViewController subclass - ios

After login succeeds my LoginViewController will loginSegue to the SASlideMenuRootViewController, which then in its own viewDidLoad automatically looks for a leftMenu segue (that I have set up to my MenuViewController) and sets this up as its leftMenu property.
This all works great but I can't see how I am supposed to pass dependencies from the LoginViewController to my MenuViewController.
Have tried the following as is the usual way to do this but it fails as obviously the leftMenu property hasn't yet been configured as viewDidLoad doesn't run until after this.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"loginSegue"])
{
// This works
SASlideMenuRootViewController *slideViewController = (SASlideMenuRootViewController *)segue.destinationViewController;
// menuViewController is nil :(
MenuViewController *menuViewController = (MenuViewController *)slideViewController.leftMenu;
// I want to pass this along
menuViewController.account = self.account;
}
}
Do I need to subclass SASlideMenuRootViewController just to pass this value along? Seems messy.
https://github.com/stefanoa/SASlideMenu

I ended up having to subclass SASlideMenuRootViewController just to pass this along.

Related

How to make work preparForSegue :sender: XCode 6?

In my app, I use segment to switch in three view. Every segmment represented with container view and they become hidden or appear according to segment. That is how my the design works, and it works well. You can find the picture below, so you can understand the structure more:
I'm having trouble with giving an instance (namely, user) created in the view controller to segment's container's view controller. I created user in the user and assign it the values. user instance has the values, I checked it. So, as usual to give with segue, I tried prepareForSegue:sender method to achieve my purpose. In the viewLoad method of the table views(you can find the table views: each of them are attached to its own container in the view controller that has segment. There are 3 containers.) user instances of table views are null. I can't give it, basically. Shouldn't the view controller pass the user value? It might being container view, but still I think it should be :) Anyway, please find below what I have written so far:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
DovizTableViewController *controller = (DovizTableViewController *)navController.topViewController;
controller.user = self.user;
}
You would remove the sender part of your code.
It should look like this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue{
//your code
//check if the next view exists by checking for the id
if ([[segue identifier] isEqualToString:#"Segue_Name"])
{
DovizTableViewController *controller = [segue destinationViewController];
controller.user = self.user;
}
}
Try this.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"YOUR_SEGUE_NAME_HERE"])
{
// Get reference to the destination view controller
DovizTableViewController *controller = [segue destinationViewController];
// Pass any objects to the view controller here, like...
controller.user = self.user;
}
}
Hope it helps.

Protocols with Navigation Controller

I have a project where I have set up a protocol to pass information back from one TableViewController to a ViewController. Everything worked fine and as expected, but I decided to embed in a Navigation Controller to the TableViewController so I could add a "DONE" barButtonItem to dismiss the Controller when the user is done. Since embedding in the navigation controller, the button works well, the TablieViewController looks identical, but none of its features and methods that use the Protocol and Delegate work, and if I remove the NavigationController everything works. Could someone explain how I can fix this issue? I am fairly new to iOS and objective c.
Here is the prepareForSegue method in the NoteViewController
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.destinationViewController isKindOfClass:[ToolTableViewController class]]) {
ToolTableViewController *targetVC = segue.destinationViewController;
targetVC.toolDelegate = self;
targetVC.autoCorrectIsOn = self.autoCorrectIsOn;
targetVC.undoAvailable = self.undoAvailable;
targetVC.redoAvailable = self.redoAvailable;
}
}
ToolTableViewController.h
#protocol ToolTableViewControllerDelegate <NSObject>
#property (weak, nonatomic) id <ToolTableViewControllerDelegate> toolDelegate;
ToolTableViewController.m - example of a method called
-(void)clearInputText{
// NSLog(#"Clear Method Selected");
[self.toolDelegate didClearInputText];
}
NoteViewController.m
-(void)didClearInputText{
self.noteTextView.text = #"";
[self dismissViewControllerAnimated:YES completion:nil];
}
Since your table view controller is embedded in a navigation controller, it's the navigation controller that will be the destination view controller of the segue. Also, it would be better to use the identifier of the segue for the if statement, rather than the class of the destination view controller (I'm using "SegueToTable" as the identifier, change that to whatever you put for the identifier). Therefore, prepareForSegue should look like this,
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"SegueToTable"]) {
UINavigationController *nav = segue.destinationViewController;
ToolTableViewController *targetVC = nav.topViewController;
targetVC.toolDelegate = self;
targetVC.autoCorrectIsOn = self.autoCorrectIsOn;
targetVC.undoAvailable = self.undoAvailable;
targetVC.redoAvailable = self.redoAvailable;
}
}
Your delegate methods are called just fine (based on the sample you pasted).
Since your controllers are embedded in a navigation controller now, you should use:
[self.navigationController popViewControllerAnimated:YES]
Before, you were presenting your controllers modally, that's why dismissViewController worked fine then but not now ( in the context of a nav controller).

Loading another view in the same viewController clears non UI properties

I have a UIViewController controlling several different views in Xcode. I want to set a label on the incoming view using information from the current view. I know labels and other UI elements get reset when the view is loaded, but my non UI #property is being set to nil as well.
Here is my property:
#property (strong, nonatomic) NSString* username;
Here is the code that sets it:
//NSLog(#"%#",dict);
if ([dict[#"login"] intValue]){
[self performSegueWithIdentifier:#"JoinSuccess" sender:sender];
self.username = dict[#"user"];
Here is the code that tries to use it:
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"%#", self.username);
self.welcomeLabel.text = [NSString stringWithFormat:#"Welcome, %#",self.username];
}
I've tried setting username both before and after performSegueWithIdentifier, but in either case when I try to reference it in viewDidLoad the value is nil. Any idea as to why it's reseting my #property? My guess is maybe it's creating a new instance of my viewController. If that's the case, how can I pass the needed variable?
As you said the viewController will be created again when ever you call performSegueWithIdentifier. You could set the value in the new instance. You can do this in
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
YourViewController *vc = [segue destinationViewController];
vc.username = dict[#"user"];
}
you have to add another method to pass value from one view controller to another view controller .
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
nextViewcontroller *nextViewcontrollerObjt = [segue
destinationViewController];
// apply setter to set value of next view
nextViewcontrollerobject.title = nextViewControllerTitleString;
nextViewcontrollerobject.variable_1= currentView_variable1;
nextViewcontrollerobject.variable_2 =currentView_variable2;
}

prepareForSegue UITableViewController using push

I'm having some trouble passing data from my UITableView to a UIViewController. I'm using PUSH in storyboard to go from my Cell to the UIViewController, and everything is working well. When I select a cell in my UITableView it pushes to the UIViewController and I get a nice back button to return to the UITableView. My problem is passing data to the UIViewController using the PrepareForSegue method ... this is what I'm doing:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"ShowUserDetailSegue"])
{
UserDetailViewController *userInfo = segue.destinationViewController;
userInfo.myLabel.text = #"Hello World";
NSLog(#"I'm here");
}
}
The label "myLabel" does not change when the UIViewController is displayed. Any idea why?
I've used prepareForSegue before and have been able to pass data, not sure what I'm missing.
Also, xcode is showing all the proper code completions and there are no errors.
Thanks!
At the prepareForSegue stage the destination viewController hasn't yet loaded it's view so userInfo.myLabel is nil.
Add a new property to UserDetailViewController, set that to your string instead and in viewDidLoad set it up in your label.

prepareForSegue and delegates

I have an application with two segues. In one of the segues, the current view controller becomes a delegate and the other does not.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"MoreOptions"]) {
UINavigationController *navigationController = segue.destinationViewController;
MoreOptionsViewController *controller = (MoreOptionsViewController *)navigationController.topViewController;
controller.delegate = self;
} else if ([segue.identifier isEqualToString:#"FullStoryView"]) {
SingleStoryViewController *detailViewController = segue.destinationViewController;
detailViewController.urlObject = sender;
}
}
All of this is working fine, but I would like to try and understand the code better. What I don't understand is that I have to get a reference to the MoreOptionsViewController by grabbing it from navigationController.topViewController rather than simply getting it from segue.destinationViewController like I do in the second if condition. Is it because I'm setting the current view controller (self) as the delegate? Again, I'm not trying to solve a problem, just trying to get a better understanding of what's going on.
Take a look at your storyboard and it should be evident why this is the case. You have embedded MoreOptionsViewController in a UINavigationController and connected a segue to the navigation controller, thus making it the destinationViewController. This is fairly common.
The delegate is largely irrelevant in the context of your question.
Your first segue's destination is a navigation controller, which contains the view controller you are really interested in. Therefore to get to that view, you need to go through the navigation controller since that won't have any properties you are interested in setting.
Your second segue goes directly to a single view controller, so you can access it directly.

Resources