Passing property value using instantiateViewControllerWithIdentifier with storyboards - objective-c

Apologies if my terminology is a bit off, new to objective C!
I am trying to pass a value from one UIViewController class to another. I am using storyboards. I am able to display the second ViewController using the following code:
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier:#"FormView"];
[self presentModalViewController:vc animated:YES];
That works fine. In my second ViewController's (FormView) header file I set a property like so:
#interface FormController : UIViewController {
NSString *selectedBooking;
}
#property (nonatomic, retain) NSString *selectedBooking;
#end
How do I "pass the value" from my first Controller to the second Controller? As far as I understand I have to set the property like so:
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier:#"FormView"];
vc.selectedBooking = #"test";
[self presentModalViewController:vc animated:YES];
Which gives me the error: Property 'selectedBooking' not found on object of type 'UIViewController'.
What is the correct way to set the property? Is there something else I should be using rather that instantiateViewControllerWithIdentifier?
Thanks

You'll need to cast it.
i.e.
FormController *fc = (FormController*)[mainStoryboard instantiateViewControllerWithIdentifier:#"FormView"];
fc.selectedBooking = #"test";
[self presentModalViewController:fc animated:YES];
then the rest of your code will work :D

Just in case if you do not wish to import the class FormController and go with it you can do as follow. really very handy:
UIStoryboard *mainStoryboard = ..
UIViewController *vc = ...
[vc setvalue:#"test" ForKey:#"selectedBooking"]; //using KVC
[self presentModalViewController:vc animated:YES];
NOTE: This will only work with properties.

Related

Search Template tvOS

Anybody know how to implement search template like in Apple tvOS Human Interface Guidelines, using native development in Objective-C or Swift, without TVML ?
So, after research I was able to find a solution:
Objective - C
If in application is tabBar, i created a subclass from UITabBarController e.g. APTabBarController. In APTabBarController, in method
- (void)viewDidLoad
I do next:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
SearchResultsViewController *myViewController = [storyboard instantiateViewControllerWithIdentifier:#"SearchResultsViewController"];
UISearchController *searchController = [[UISearchController alloc] initWithViewController:myViewController];
UISearchContainerViewController *containerVC = [[UISearchContainerViewController alloc] initWithSearchController: searchController];
containerVC.title = #"Search";
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController: containerVC];
NSMutableArray *newTab = [self.viewControllers mutableCopy];
[newTab addObject: navigationController];
[self setViewControllers: newTab];
Where:
storyboard - is my storyboard
SearchResultsViewController - is my controller from storyboard that contains collectionView
UISearchController - is controller that allow to find what do you need
UISearchContainerViewController - and these one is like a view controller from tabBarController
In "newTab" - I add fresh created viewController that i need
But, problem that I found is that i can't catch searched text. For that, create a subclass from UISearchController, and implement custom
initWithViewController
In my case it looks like these:
In .h
#import <UIKit/UIKit.h>
#interface SearchExercisesViewController : UISearchController
- (id) initWithViewController:(UIViewController *) viewController;
#end
In .m
#import "SearchExercisesViewController.h"
#interface SearchExercisesViewController () <UISearchBarDelegate>
#property (nonatomic, strong) UIViewController *viewController;
#end
#implementation SearchExercisesViewController
- (id) initWithViewController:(UIViewController *) viewController {
self = [super initWithSearchResultsController:viewController];
if (self) {
self.viewController = viewController;
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.searchBar.delegate = self;
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
NSLog(#"%#",searchText);
}
#end
Profit, and now, replace
UISearchController *searchController = [[UISearchController alloc] initWithViewController:myViewController];
with
SearchExercisesViewController *searchController = [[SearchExercisesViewController alloc] initWithViewController:myViewController];
All done. Now only that remain is to sent data to viewController that contains collection view, and implement logic for search. For sent data you can you Delegate pattern or NSNotification. You can find how to implement that in that post:
it possible to Pass Data with popViewControllerAnimated?
Swift
In swift is the same, how to do that, you can find on Apple example from these link:
https://github.com/brunogb/TVExamples/tree/master/UIKitCatalogtvOSCreatingandCustomizingUIKitControls
Sounds like you want to look at UISearchController.

UIPopovercontroller in UISplitViewController

My detailviewcontroller is called myDetailVC , with tableVC which is just a table on the side of myDetailVC.
in myDetailVC, I have a button that is supposed to show a popoverviewcontroller. However, it crashes when I press it.
in my .h file:
#property (strong, nonatomic) UIPopoverController *masterPopOverController;
and .m:
- (IBAction)goToPDF:(id)sender
{
viewPDFViewController *MPPWV =[[viewPDFViewController alloc] initWithNibName:nil bundle:nil];
self.masterPopOverController = [[UIPopoverController alloc] initWithContentViewController:MPPWV];
[self.masterPopOverController presentPopoverFromRect:[sender frame] inView:[sender superview] permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
[self.masterPopOverController setPopoverContentSize:CGSizeMake(100, 100) animated:NO];
}
Everything is connected fine in my xib, since I tested it by making it push to a viewcontroller instead of a popover. Can someone help me with this?
First, it looks like you're loading it up with a view controller that doesn't have anything in it:
viewPDFViewController *MPPWV =[[viewPDFViewController alloc] initWithNibName:nil bundle:nil];
Try specifying a Nib name, if you have one. It's possible that you don't have a NIB for that view controller. If that's the case you probably have a designated initializer -init method that you should be calling on it. Do that instead of calling -initWithNibName:
Second, it doesn't look like you're retaining the view controller you're loading into the pop over. It's possible that they require strong references. Try retaining it via property (or an ivar):
#property (nonatomic, strong) viewPDFViewController * MMPPWV;
Then when you access it do so via self:
self.MPPWV = [[viewPDFViewController alloc] initWithNibName:nil bundle:nil];

Switch Active View Controller Programmatically

I have 2 views as part of my Navigation Controller.
I created a class for my Navigation Controller with a public method that certain actions on the first view will trigger to load the Detail View Controller. I am importing the Detail View Controller, but nothing in my code is working. I know the method is being called correctly because I'm logging it.
What am I doing wrong here?
#import <UIKit/UIKit.h>
#interface NearbyController : UINavigationController
- (void) nextpage;
#end
#import "NearbyController.h"
#import "DetailView.h"
#implementation NearbyController
-(void) nextpage {
NSLog(#"working");
DetailView *nextView = [[DetailView alloc] init];
[self pushViewController:nextView animated:YES];
}
#end
If you initialize a view controller programmatically you should use this init.
If you have set a storyboard ID you can do this
DetailView *nextView = (DetailView *)[self.storyboard instantiateViewControllerWithIdentifier:#"DetailViewControllerID"];
[self pushViewController:nextView animated:YES];
If you want to load from a XIB you can call
DetailView *nextView = [[DetailView alloc] initWithNibName:#"MyDetailViewControllerID" bundle:nil];
[self pushViewController:nextView animated:YES];
Hope it helps!
If you're using storyboards what you wanna do is setup the storyboard id in the identity inspector on your DetailViewViewController
Then you would wanna instantiate your view controller like so:
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
DetailView *nextView =[sb instantiateViewControllerWithIdentifier:#"DetailViewViewController"];
/* your identifier is your storyboard id*/
sb = nextView.storyboard;
Then you should be able to push your view controller.
Im still new to this but i hope this helps!

Syntax error trying to set a property value

I want to pass a id from table view (TableViewController) to another view (ViewController) after tap a table cell. I have declared a storyboard ID "ViewController" for ViewController
Here is TableViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle: nil];
UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:#"ViewController"];
viewController.id=#"test";
[self.navigationController pushViewController:viewController animated:YES];
}
Here is ViewController.h
#property (nonatomic) NSString *id;
ViewController.m
- (void)viewDidLoad{
id= [[NSString alloc] init];
}
But the statement viewController.id=#"test"; occurred the syntax error.
id is a reserved word in Objective-C. Do not name any variable or property id. Rename it to something else.
Also, your viewController variable is declared as UIViewController. There is no id property in UIViewController. Change the type of viewController to the actual type it is (ViewController?).
ViewController *viewController = (ViewController *)[storyboard instantiateViewControllerWithIdentifier:#"ViewController"];
Check the link below, covers these basics for beginners on how to pass data between UITableViewController to another view.
Storyboards Segue Tutorial: Pass Data Between View Controllers
By the way, i don't think you can use "id" as your property name.

How to access other viewcontrollers variables/properties in xcode

I know similiar questions have been asked before, but please bear with me as I am totally new at Objective C (have good knowledge on C).
My case is that I have a tab bar controller with two windows. When I press a button in "second" I change a variable changeName. I want to use the value of changeName in my "first" view controller but stumbled on to some problems:
To reach the other viewcontroller I found this from SO (unfortunately I forgot where):
-(NSString *)newName{
// Create a UIStoryboard object of "MainStoryBoard_iPhone" named storyboard
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:(NSString *)#"MainStoryBoard_iPhone" bundle:(NSBundle *)nil];
// Create a UIViewController object of the wanted element from MainStoryBoard_iPhone
UIViewController *secondview = [storyboard instantiateViewControllerWithIdentifier:(NSString *)#"secondBoard"];
return secondview.changeName;
}
Which I have in my first.m. MainStoryBoard_iPhone is the name of the .xib/storyboard-file.
but no. Error says
Property 'changeName' not found on object of type 'UIViewController *'
In my second.h I have
#property (readwrite, retain) NSString *changeName;
and in second.m
#synthesize changeName;
All help is appreciated, but please keep in mind that I have only used OOP for two days.
Thank you all in advance
EDIT: And what input should I have here?
- (void)viewDidLoad
{
[super viewDidLoad];
mylabel.text = Name; // or [mylabel.text Name] or something?
}
You need to cast the view controller returned to your customized second view controller (as UIViewController does not have the property changeName).
So do the following :
// Create a UIViewController object of the wanted element from MainStoryBoard_iPhone
SecondViewController *secondview = (SecondViewController *)[storyboard instantiateViewControllerWithIdentifier:(NSString *)#"secondBoard"];
I assume SecondViewController is the name of your second controller.
In my case I wanted to pass a string from FirstViewController to set a text field in SecondViewController, so:
1- In SecondViewController.h
#property (strong, nonatomic) IBOutlet UITextField *someTextField;// this is linked to a UITextField
2- In FirstViewController.m:
#import "SecondViewController.h"
3- I will do this after a press of a button in the FirstViewController:
SecondViewController *SecondView = [[SecondViewController alloc]
initWithNibName:#"SecondViewController" bundle:nil];
//set fields values
SecondView.someTextField.text = #"HeLLO from First";
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController: SecondView];
//show AdView
[self.navigationController presentViewController:nav animated:YES completion:nil];
4- This is it!
5- There is a case, if I'm in FirstViewController and wanted to set a string property in the SecondViewController with the same way, the string won't get the value till you press a some kinda button in SecondViewController, it won't get it like in viewDidLoad for example! don't know why.