This question already has answers here:
Accessing a swift property from objC
(2 answers)
Closed 5 years ago.
UITapGestureRecognizer *gesture = (UITapGestureRecognizer *) sender;
NSInteger userID = gesture.view.tag;
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"Main"
bundle:nil];
OthersProfile *vc = (OthersProfile*)[storyboard instantiateViewControllerWithIdentifier:#"othersprofile"];
NSString *strUserID = [NSString stringWithFormat:#"%ld", (long)userID];
vc.userID = strUserID;
[self.viewController.navigationController pushViewController:vc
animated:YES];
I am trying to access another view's variable and assign a value.
I declared that userID var on another view as
var userID = String()
But it says Property 'userID' not found on object of type 'OthersProfile *'?
Any idea how can i fix this?
Check the access modifiers on the var and its parent class.
this declaration
class OthersProfile:UIVIewController {
var userID = String()
}
will not always expose your inner variable. It depends on your project setup.
You can always check the contents of the "MyModule-Swift.h" synthetic header by Command-clicking it to see what has been exposed by the Swift compiler and how it has converted the Swift attributes to Objective-C
You want to get something like this
SWIFT_CLASS("_TtC5MyModule22OthersProfile")
#interface OthersProfile : UIViewController
#property (nonatomic, copy) NSString* _Nonnull userID;
The easiest way through is to start marking inaccessible things as public or open e.g
public class OthersProfile:UIVIewController {
var userID = String()
}
or
class OthersProfile:UIVIewController {
public var userID = String()
}
Later on you can back the access off if important.
I don't know nothing about objective C, but to me... probabily the problem is your cast.
Please verify what type is your VC with X-Code.. probabily is a ViewControler... and not your CustomViewControler.
Related
I want to send a dictionary from Objective-C Controller into Swift controller. I have tried using the keyword #obj-c, Public in Swift controller but couldn't access.
Objective-C code:
vc_listing_list *swiftController = [[vc_listing_list alloc] init];
swiftController = (vc_listing_list *)[storyboard instantiateViewControllerWithIdentifier:viewControllerID];
Here I want to access "selectedDirectory" variable to send dictionary value.
Swift Code:
#objc class vc_listing_list: UIViewController {
var selectedDirectory: Dictionary<String, String>
}
I expect my code in objective c controller:
vc_listing_list *swiftController = [[vc_listing_list alloc] init];
swiftController = (vc_listing_list *)[storyboard instantiateViewControllerWithIdentifier:viewControllerID];
swiftController.selectedDirectory = someDictionary; // this line am expecting.
add #objcMembers to swift file
#objcMembers class vc_listing_list: UIViewController {
var selectedDirectory: Dictionary
}
if you are using storyboard then, you don't need to initialize like this
vc_listing_list *swiftController = [[vc_listing_list alloc] init];
you can directly use like this
vc_listing_list * swiftController = [storyboard instantiateViewControllerWithIdentifier:#"viewControllerID"];
swiftController.selectedDirectory = someDictionary
[self.navigationController pushViewController:swiftController animated:YES];
Please try to correct your class and object naming convention also.
thanks
To access an Objective-C class from Swift you need to add it to the bridging header. The bridging header is normally named after your target name e.g. MyApp-BridgingHeader.h
You import any headers that you need for Swift in the bridging header:
#import "VCListingList.h"
From there you can access the class from within Swift.
let controller = VCListingList()
So for your issue you would need to expose the selectedDirectory in the Header as a property complete with bridging types of <NSString *,NSString *>.
It would be your choice to make it Optional using nullable. If you don't want it to be Optional you must initialise the property before reading it in Swift.
NS_ASSUME_NONNULL_BEGIN
#interface VCListingList: UIViewController
#property (nonatomic, strong, nullable) NSDictionary<NSString *,NSString *>* selectedDictionary;
//the rest of your header stuff
#end
NS_ASSUME_NONNULL_END
Style note: don't use lower case for class names. It makes them easy to confuse with variables. So VCListingList is preferred to vc_listing_list
You can read the documentation for more information
There are several ways to pass data from objective c to swift class.
1) using NSUserDefault
NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
[dic addObject:#"sss" forKey:#"hi"];
[dic addObject:#"eee" forKey:#"hr"];
[NSUserDefaults standardDefaults] setObject:dic forKey:#"DicKey"];
[[NSUserDefaults standardDefaults] synchronize];
then get data in swift class
let dic = NSUserDefaults.standard.string(forKey: "DicKey")
2) Using direct create object of swift class.
var dic : [[String:Any]]!
pass dict like this
NSMutableDi
ctionary *dic = [[NSMutableDictionary alloc] init];
[dic addObject:#"sss" forKey:#"hi"];
[dic addObject:#"eee" forKey:#"hr"];
SwiftViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"SwiftViewController"];
SwiftViewController.dict = dict
[self.navigationController pushViewController:vc animated:YES];
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.
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
}
I am new to IOS Programming. I am sending an integer value to another view controller from segue like this:
SlideShowViewController *destViewController = segue.destinationViewController;
[destViewController setSelectedButton:tagIndex];
I am successfully accessing this value in my SlideShowViewController.m file:
#synthesize selectedButton;
NSLog(#"%i",selectedButton);
Now I want to access this same value which saved in selectedButton in my other View Controller. So I did this in my viewDidLoad of AnotherViewController:
SlideShowViewController *button= [[SlideShowViewController alloc] init];
NSLog(#"selected button is %i",button.selectedButton);
But I am not getting the value here.
While going to second view controller do same as you did for first
SecondViewController *destViewController2 = segue.destinationViewController;
[destViewController2 setSelectedButton:tagIndex];
In your SlideShowViewController.h create a property to hold data.
In your SlideShowViewController.m synthesize property and remove
SlideShowViewController *button= [[SlideShowViewController alloc] init];
this line from SlideShowViewController.m. In this line your are creating new instance of SlideShowViewController.
In the last code section, you're creating a new instance of the SlideShowViewController. This instance won't have the same variables as the first instance. In order to access the selectedButton field, you need to have a reference to your first SlideShowViewController instance to access its properties.
// Here you create a new instance. You need to hang onto the destViewController
// pointer if you want to access its selectedButton property later. This means
// you'll need to use a global variable, or otherwise expose it in some way for
// future reference.
SlideShowViewController *destViewController = segue.destinationViewController;
[destViewController setSelectedButton:tagIndex];
Later, possibly in a different method, you could do something like:
// Note, we're referring to destViewController using self. I'm assuming you've
// set up a property on the self object to refer to destViewController outside
// of the scope of the initial initialization.
int selectedButtonIndex = self.destViewController.selectedButton;
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 ---
}