In iOS how to get object fromViewController name? - ios

I know that this is double question. I know that I can use property in toViewController to get name of UIViewController to get NSString which tells me where I am coming from.
Anyway I want to ask if there a simple way to get name of UIViewController when unwinding from segue.
I have a UIViewController with segues to 3 forms. I programatically return to that view controller. I need to run a specific code only when I am returning from one of view controllers. My goal is using string from name of fromViewController start that specific code.

Using UIViewController by NSString from its class name isn't safe enough because the name can be changed.
You can use isKindOfClass instead:
UIViewController *destinationViewController = segue.destinationViewController;
if ([destinationViewController isKindOfClass:[MyViewControllerClass1 class]]) {
// put code related to transition to MyViewControllerClass1
}
else if ([destinationViewController isKindOfClass:[MyViewControllerClass2 class]]) {
// put code related to transition to MyViewControllerClass2
}

You can use:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
UIViewController *destinationViewController = segue.destinationViewController;
NSString * identifier = destinationViewController.identifier;
NSString * title = destinationViewController.title;
}

Create a Custom delegate method in the primary VC, create 3 strings with unique name so that u can identify.
EG.
NSString* stringFrmFORM1, *stringFrmFORM2, *stringFrmFORM3;
-(void)setString:(NSString*)myString{
//set the string from the VC1,2,3 to each string based on Primary VC's strings
}
Call the delegate method from each registration VC, and set those Strings.
You will have your registration strings to each of the Unique strings that you have set, from each of the Registration VC's.

To answer your base question, you can get the name of a class in string form with:
NSString *strClassName = NSStringFromClass([fromViewController class]);
but as #AlexPeda pointed out in ze answer, -isKindOfClass: would be better.
if ([fromViewController isKindOfClass:[SpecificViewController class]]) {
//run your 'specific' code
}

Related

access to property found with isMemberOfClass

How can I get access to a property of a ViewController when I have created an object of it like this:
for (UIViewController* vc in self.navigationController.viewControllers)
{
if ([vc isMemberOfClass:NSClassFromString(#"myViewController")])
{
// change property value on viewcontroller vc, for instance: vc.myText = #"hello" ??
}
}
thanks in advance!
You need to cast to let the compiler know the data type (or cheat and set it by an indirect method):
myViewController *mvc = (myViewController *)vc;
mvc.myText = #"hello";
Note also that class names should start with a capital first letter.
Just use simply like this:
(myViewController *)vc.myText = #"hello"
myText needs to be public variable also.

Same view controller UI, different functionality

I have a view controller whose UI is the identical between 2 classes, but the functionality is different. One of the classes uses the view controller to add a contact, the other uses it to edit a contact.
Is there a way to "reuse" the layout/view of the view controller while having different classes (add/edit class)?
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqual:#"AddContact"]) {
UINavigationController *navigationController = segue.destinationViewController;
AddContact *addContact = (AddContact *)navigationController.viewControllers.firstObject;
addContact.delegate = self;
}
else if ([segue.identifier isEqual:#"EditContact"]) {
EditContact *editContact = (EditContact *)segue.destinationViewController;
editContact.currentContact = [self.contacts objectAtIndex:[[self.tableView indexPathForSelectedRow] row]];
}
}
The segue.destinationViewController is of type ViewContact which both AddContact and EditContact both inherit from. All it does it hold onto the outlets for the textfields that both of its children use.
Unfortunately, the snippet above doesn't work because you can't really typecast parents to their children.
What I normally do is create a single view controller, with a xib included, and add a property like so:
header file
typedef NS_ENUM(NSUInteger, CRUD) { //Create, Read, Update, Delete
CTCreate,
CTRead
};
#property ( assign, readonly ) CRUD option;
And in the initialization of this view controller you'd have something like:
header
- (id)initWithOption:(CRUD)optionValue;
implentation
- (id)initWithOption:(CRUD)optionValue {
...
option = optionValue;
return self;
}
And in the implementation of this class you'd have if statements where the differences are, like when the user hits saves, should this class insert a new record, add, or update a recorded, edit
Hope this helps :) feel free to ask for more clarification :)p

Pass data between two ViewControllers [duplicate]

This question already has answers here:
Passing data between view controllers
(45 answers)
Closed 7 years ago.
I need to pass data between two ViewControllers but without UIButton, in a few words, I need to access a variable which is in other ViewController.
My code is:
LoginViewController *lvc;
NSString name=lvc.name;
This specific case might be a little easier than delegates.
From what I see, you're trying to pass login credentials (name/login/password/something). I would use two things depending on the actual matter here.
Either NSUserDefaults or -performSegueWithIdentifier:
NSUserDefaults is a file that is loaded in every app that you can read and edit, simply using the following commands :
Setting a variable :
NSString *aName;
[[NSUserDefaults standardUserDefaults]setObject:aName forKey:#"userName"];
Getting a variable :
NSString *aName = [[NSUserDefaults standardUserDefaults]objectForKey:#"userName"];
Note that you can save the following objects NSDictionary, NSArray, NSString, NSNumber, NSData, and probably a couple that I'm forgetting but someone can edit if I do.
Note that this file is loaded at every startup, so you don't wanna use that as a database but more of a small-sized storage easy to use, like for user name, preferences/settings, and stuff like that.
The other way is using performsegue between two controllers, but that requires storyboards.
Drag a segue between two of your controllers, name it (for example) fromLoginToHome. I'm assuming that the flow goes from the login controller to the home controller.
when you move between the two views (when the user presses "Login" for example), call this method
[self performSegueWithidentifier:#"fromLoginToHome" sender:self];
Then you'll need to implement this method, that is usually there but in a comment block (it's always like that when you create your Vc)
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([segue.identifier isEqualToString:#"fromLoginToHome"]){
HomeViewController *vc = (HomeViewController*)segue.destinationViewController;
vc.myName = _myName;
}
}
Xcode using delegate to pass data between controllers This is for child to parent by usuing delegates
And For parent to child,you can use segues simply.
HTH!enjoy Coding.
You can have a look of delegate method in here delegate. can you tell me if you are looking for delegate or not
Try using as below
FirstViewController.h
#interface FirstViewController: UIViewController
- (void)GetItNow;
FirstViewController.m
- (void)GetItNow{
NSLog(#"I acheived"); }
- (IBAction)goToSecondView:(id)sender {
SecondViewController* Second= [[SecondViewControlleralloc] initWithNibName:#"SecondViewController" bundle:nil];
rqVC.addId = self.addId;
[self.view addSubview:Second.view];
}
SecondViewController.h
#property (nonatomic, assign) id delegate;
SecondViewController.m
- (IBAction)Action_LoadFunds:(id)sender {
[self.view removeFromSuperview];
[_delegate GetItNow];
}

Passing string between UIViewControllers.

In ViewContrller1.h :
#property (retain,nonatomic) NSString *myString;
In ViewController2.m , I want to read a value from a text box and assign it to viewContrller1.theString and go to ViewContrller1
I used this method but I get a null value of my string in ViewContrller1:
- (IBAction)buttonPressed:(id)sender {
ViewContrller1 *go=[self.storyboard instantiateViewControllerWithIdentifier:#"ViewContrller1"];
go.myString=self.myTextFeild.text;
[self.navigationController pushViewController:go animated:YES];
}
Wondering how it suppose to work?
try to simple import viewcontrller1.h in the new view controller.
#import "viewcontrller1.h"
Marcal's answer should also work.
To pass properties between 2 views, the recieving view must have a public property. For example, your VC 2 shoud have a public NSString. This means declared on your .h file. Then on your initial VC you have to pass the string on the prepareForSegue method. Something like that here:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"vc2segue"]) {
UIViewController *vc=segue.destinationViewController;
vc.publicNstring=self.someTextView.text;
}
}
There is nothing wrong with the code that you've posted, assuming you've made no typos and have connected the text field and the button to your second view controller (the one sending the string) and that you've added the Storyboard ID to the first view controller within your storyboard - see here http://sketchytech.blogspot.co.uk/2012/11/instantiate-view-controller-using.html
Assuming you've also embedded the view controller within a Navigation Controller, then a line of code in viewcontrller1.m (viewDidLoad:):
NSLog(#"%#",self.myString);
Should confirm it works. In fact, I just tested it with your code and it works. Check for typos would be my advice if you've done all of the above.

Programmatically get a Storyboard ID?

Trying to see if a UIViewController or UIView can identify its Storyboard ID. So was hoping for:
UIViewController *aViewController;
NSString *storyboardID = aViewController.storyboard.id; //not an actual property
or:
NSString *storyboardID = [aViewController.storyboard valueForKey:#"storyboardId"]; //also not a working call
But no joy and couldn't find a similar solution online. Does anyone know if this is even possible?
You can use the restorationIdentifier, it's right above the Storyboard identifier and it's a UIViewController property.
You can use the Restoration ID:
NSString *restorationId = self.restorationIdentifier;
Just check the checkbox 'Use Storyboard ID'
The storyboard id is only meant to find and instantiate a VC from a storyboard.
As written in the UIStoryboard reference:
"This identifier is not a property of the view controller object itself and is only used by the storyboard file to locate the view controller."
Why do you need it?
You can also try doing something like this:-
NSString *storyboardId = [viewController valueForKey:#"storyboardIdentifier"];
This will precisely give you the Storyboard Id that you have set via interface builder.
Swift extension:
extension UIViewController {
var storyboardId: String {
return value(forKey: "storyboardIdentifier") as? String
}
}
The most reliable method for returning the "id" of the UIViewController or UIView is...
NSString *viewControllerName = [[NSString alloc] initWithString:viewController.nibName];
This will return... "29w-Ic-LNo-view-FDu-oq-UpZ", where "29w-Ic-LNo" is the Object ID of the UIViewController and "FDu-oq-UpZ" is the Object ID of the UIView.
However, you may also use...
NSString *viewControllerName = [[NSString alloc] initWithString:viewController.title];
This will return the "Title" of the UIViewController in the Attributes Inspector; so just as easily as you added the Storyboard ID to the UIViewController, you may also add a title.
You can compare with class name .
import class and then try.
NSArray *viewControllers = self.navigationController.viewControllers;
UIViewController *root = [viewControllers objectAtIndex:0];
if ([root isKindOfClass:[UserLogin class]]) {
//--- do ---
}

Resources