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.
Related
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.
I am attempting to pass the label for a given selected cell to a different view controller...
ListViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSIndexPath *selectedIndexPath = [self.tableView indexPathForSelectedRow];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:selectedIndexPath];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Storyboard" bundle: nil];
DetailViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:#"DetailVC"];
viewController.venueName = cell.textLabel;
[self.navigationController pushViewController:viewController animated:YES];
}
Here is my DetailViewController:
.h
#interface DetailViewController : UIViewController {
IBOutlet UILabel *venueName;
}
#property (nonatomic, strong) IBOutlet UILabel *venueName;
venueName never gets the data. In my .m I also synthesize the venueName.
This happens because your UILabel outlet is not connected at the time you set a string for it. I recommend you to create a string property to store the value and, in viewDidLoad in DetailViewController, you set the string to venueName.
Cheers!!
You need to modify the below like that for setting and getting the text:-
viewController.venueName.text = cell.textLabel.text;
So venueName, which is a pointer to a label, is made to point to an existing label that's part of a table cell. This is obviously wrong -- you don't mean to use the actual label from the table cell, but rather the text stored in it. Both the other answers here are correct: you surely mean to assign the text property of one label to that of the other, and the label that outlet viewController.venueName is connected to hasn't been created at the time this code executes.
The immediate thing you should do to fix your code is to assign the data in question (i.e. cell.textLabel.text) to a string property in the destination view controller. Have the -viewDidLoad or -viewWillAppear method in that controller set the text property of the venueLabel label. Either of those methods will be called after the view hierarchy is instantiated.
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.
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.
I'm new to iOS and Objective-C. I have an application that displays a table view, and opens a new view when click the user clicks on a row.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
DetailViewController *detailController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
[detailController changeSubjectText:[subject_data_Array objectAtIndex:indexPath.row]];
//navigationController = [[UINavigationController alloc] initWithRootViewController:detailController];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
}
In my detail view I have coded:
-(IBAction)closeDetail:(id)sender {
NSLog(#"closeDetail");
[self.view removeFromSuperview];
}
But it's not working. Can anyone help?
Can anyone help me?
how i can close view?
download my code in --> http://www.vasuta.com/ios/multiview2.zip
open build and run click one row in "Bulletin Board" DetailView it's open click Close …..
why DetailView is not full screen and why can't close detail view?
i open it wrong or i close it wrong
help me please
didSelectRowAtIndexPath you can see in "GadgetBulletinsTVContoller.m" and close command you can see in "DetailViewController.m"
Thank you very much
ps. sorry for my english skill :(
Why are you creating that window object and why are you trying to add your subview to it?
if you want to add a subview you should add it to the parent, the tableview or the parent of the tableView.
a better idea would be to push a new view controller on the stack that would display the info you want to show.
Here is a tutorial that shows how to push a new view controller when selecting a cell in a tableview tutorial link .
EDIT:
in MultipleAppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions should look like below:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[MultipleViewController alloc] initWithNibName:#"MultipleViewController" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
navController.navigationBarHidden = YES;
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
return YES;
}
In GadgetBulletinsTVContoller.h declare a protocol like below:
#protocol GadgetBulletinsTVControllerDelegate <NSObject>
#optional
- (void)showItemDetails:(id)selectedItem;
#end
and a delegate property:
#property (nonatomic, assign)id<GadgetBulletinsTVControllerDelegate>delegate;
In GadgetBulletinsTVContoller.m synthesize the delegate.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
should look like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if([delegate respondsToSelector:#selector(showItemDetails:)])
{
[delegate showItemDetails:[subject_data_Array objectAtIndex:indexPath.row]];
}
}
In FirstViewController.m tell the controller to implement the GadgetBulletinsTVControllerDelegate like this:
#interface FirstViewController ()<GadgetBulletinsTVControllerDelegate>
in viewDidLoad method tell the gadgetBulletinsController that his delegate is the FirstViewController class, like this:
if (gadgetBulletinsContoller == nil) {
gadgetBulletinsContoller = [[GadgetBulletinsTVContoller alloc] init];
gadgetBulletinsContoller.delegate = self;
}
and implement the GadgetBulletinsTVControllerDelegate's methods:
- (void)showItemDetails:(id)selectedItem
{
if([delegate respondsToSelector:#selector(showDetailsScreenForItem:)])
{
[delegate showDetailsScreenForItem:selectedItem];
}
}
In FirstViewController.h declare a protocol like below:
#protocol FirstViewControllerDelegate <NSObject>
- (void)showDetailsScreenForItem:(id)item;
#end
and declare a delegate property like below(don't forget to synthesize in .m file):
#property (nonatomic, assign)IBOutlet id<FirstViewControllerDelegate>delegate;
In MultipleViewController.xib select the FirstViewController screen and in outlets drag from the delegate to the fileOwner for setting the value of the delegate to the MultipleViewController(you can do this in code if you want to).
In MultipleViewController.m tell the MultipleViewController to implement the FirstViewControllerDelegate protocol like below:
#interface MultipleViewController ()<FirstViewControllerDelegate>
and implement the protocol method:
- (void)showDetailsScreenForItem:(id)item
{
DetailViewController *detailController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
[detailController changeSubjectText:item];
[self.navigationController pushViewController:detailController animated:YES];
}
In DetailViewController modify the closeDetail method to look like this:
- (IBAction)closeDetail:(id)sender {
NSLog(#"closeDetail");
[self.navigationController popViewControllerAnimated:YES];
}
and voila, Your GadgetBulletinsTVController items details are pushed. You need to do the same steps for the other controllers from where you want to show details.
instead of removing the view from window just reload the basic view which contains all the table views using self.window.rootviewcontroller
EDIT
i got the solution by creating appDelegate what you have to do is just described below
First .h and .m file of AppDelegate Here (MultipleAppDelegate)
in .h add
#property (strong, nonatomic) id<UIApplicationDelegate>delegate;
in .m add
#synthesize delegate;
now where ever you like to add detailView just add below in .h and .m files as described
in .h file here(GadgetBulletinsTVContoller)
#import "MultipleAppDelegate.h"
and in interface one variable like this
MultipleAppDelegate *Mydelegate;
in .m file in viewDidLoad or loadView method
Mydelegate = [[UIApplication sharedApplication]delegate];
then at loading the detailView do this
navigationController = [[UINavigationController alloc] initWithRootViewController:detailController];
Mydelegate.window.rootViewController = navigationController;
[Mydelegate.window makeKeyAndVisible];
now at the detailViewController's .h and .m files
in .h file
#import "MultipleAppDelegate.h"
and in interface
MultipleAppDelegate *appDelegate;
in .m file in viewDidLoad or loadView method
appDelegate = [[UIApplication sharedApplication]delegate];
and on close button click
//Not required
//[self.navigationController popViewControllerAnimated:NO];
appDelegate.viewController = [[MultipleViewController alloc] initWithNibName:#"MultipleViewController" bundle:nil];
appDelegate.window.rootViewController = appDelegate.viewController;
[appDelegate.window makeKeyAndVisible];
That's all it will work fine only problem is that it take's 1 or 2 seconds to navigate and show the multipalViewController
enjoy Coding :)
Happy Coding :)