I want to pass some core data from master to detail.
First the user selects a name which has a gender assigned. If gender Girl "pige" it goes to the girls UITableiew. From there each selection shows on detail view.
I want to pass some data from the girl UITableiew. Like if its a girl color it pink. set a title etc.
So far i know how to pass around the UITableiew "master" but not how to get it to the detail view
Here's some code on how i manage the selection of UITableView etc.
DetailViewContainerController
UIStoryboard* initial = [UIStoryboard storyboardWithName:#"Main-iPad" bundle:nil];
self.initital = [initial instantiateViewControllerWithIdentifier:#"initialSite"];
[self addChildViewController:self.initital];
self.startSide = [initial instantiateViewControllerWithIdentifier:#"startSide"];
[self addChildViewController:self.startSide];
-(void)initialSite:(int)viewId
{
UIViewController *viewController;
switch (viewId)
{
case 0:
viewController = self.initital;
[self.navigationController setNavigationBarHidden:NO animated:NO];
break;
case 1:
viewController = self.startSide;
[self.navigationController setNavigationBarHidden:NO animated:NO];
break;
}
[self showChildViewController:viewController];
}
-(void)showChildViewController:(UIViewController*)content
{
if(topController != content)
{
content.view.frame = [self.view frame]; // 2
[self.view addSubview:content.view];
[content didMoveToParentViewController:self];
topController = content;
}
}
startTableViewController
-(void)viewDidLoad
{
arrayA = [[[NSMutableArray alloc] initWithArray:[Start findAllSortedBy:#"navn" ascending:YES]] mutableCopy];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([[[self.fetchedResultsController objectAtIndexPath:indexPath] valueForKey:#"gender"]isEqualToString:#"Pige"])
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main-iPad" bundle:nil];
DetailViewContainerController *controller = [storyboard instantiateViewControllerWithIdentifier:#"MenuPige"];
controller.forNavn = [arrayA objectAtIndex:indexPath.row];
[self.navigationController pushViewController:controller animated:YES];
}
if ([[[self.fetchedResultsController objectAtIndexPath:indexPath] valueForKey:#"gender"]isEqualToString:#"Dreng"])
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main-iPad" bundle:nil];
DetailViewContainerController *controller = [storyboard instantiateViewControllerWithIdentifier:#"MenuDreng"];
controller.forNavn = [arrayA objectAtIndex:indexPath.row];
[self.navigationController pushViewController:controller animated:YES];
}
}
MenuPige
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.detailViewContainerController initialSite:[indexPath row]];
if ([[[self.fetchedResultsController objectAtIndexPath:indexPath] valueForKey:#"menuPunkt"]isEqualToString:#"Barnedåb / Navngiving"]) {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"BarneDaab" bundle:nil];
DetailViewContainerController *controller = [storyboard instantiateViewControllerWithIdentifier:#"barneDaab"];
[self.navigationController pushViewController:controller animated:YES];
}
in the girl menu.h i have the NSStrings of the data that i want to pass. So that is working. but how to get it to detailviewcontroller ?
UPDATE:
I tried this Accessing array from a detail view controller into master view controller in Objective-C
but can't get it work
UPDATE 2:
self.navigationController.parentViewController.navigationItem.title = [self.detailViewContainerController.forNavn valueForKey:#"navn"];
doesn't work in the velkommen.m, it returns nil
UPDATE 3:
Leftmenucontroller.m - this works. but only to another uitableview. can't get it over to the detail view
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailViewContainerController *start = [[DetailViewContainerController alloc]init];
start.forNavn = forNavn;
NSLog(#"leftview = %#", forNavn);
[self.detailViewContainerController initialSite:[indexPath row]];
}
UPDATE 4:
startTableViewController.h
{
NSMutableArray *arrayA;
NSMutableArray *tableData;
NSString *forNavn;
NSString *mellemNavn;
NSString *efterNavn;
NSString *gender;
}
#property (nonatomic, retain) NSString *forNavn;
#property (nonatomic, retain) NSString *mellemNavn;
#property (nonatomic, retain) NSString *efterNavn;
#property (nonatomic, retain) NSString *gender;
#property (nonatomic, strong) NSMutableArray *arrayA;
UPDATE 6:
I figured out that i can pass the data to DetailviewContainerController with this
DetailViewContainerController *test = (DetailViewContainerController *) [[self.splitViewController.viewControllers lastObject] topViewController];
test.leftViewController = self;
test.forNavn = forNavn;
NSLog(#"test = %#",test.forNavn);
but now i can't get it further from DetailViewContainerController. i tried this :
VelkommenViewController *test2 = (VelkommenViewController *) [[self.splitViewController.viewControllers lastObject] topViewController];
test2.detailViewContainerController = self;
test2.forNavn = self.forNavn;
NSLog(#"test2 = %#",test.forNavn);
Update 7:
Update 8:
VelkommenViewController *test2 = [[[self.splitViewController.viewControllers.lastObject topViewController] childViewControllers] objectAtIndex:0];
test2.forNavn = forNavn;
NSLog(#"test3 = %#",test2.forNavn);
Throws a error : -[UINavigationController setForNavn:]: unrecognized selector sent to instance 0x175b56c0
Update 9:
It's a little unclear what you're doing, especially with the child view controller stuff. But, in general, when working with a split view controller, the detail controller can be accessed by using self.splitViewController.viewControllers[1] (if the detail controller is embedded in a navigation controller, then that gets you a reference to the navigation controller, and you have to use its topViewController property to get to the detail controller). You shouldn't be using instantiateViewControllerWithIdentifier:, or alloc init to access the detail controller, since either of those methods will give you a new instance instead of referencing the one you have on screen.
on the receiving end this works:
NSString *name = ((DetailViewContainerController *)self.parentViewController).forNavn;
Related
I'm trying to pass a NSDictionaryfrom a TableViewControllerto a ViewController. In my TableViewController.m. I have this code to navigate to the ViewController:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *objectDict = [dataArray objectAtIndex:indexPath.row];
NSLog(#"Info: %#", objectDict);
// Pass object to new page
//UIViewController * vc = [[UIViewController alloc] init];
//[self presentViewController:vc animated:YES completion:nil];
SeeInfoVC *controller = [[SeeInfoVC alloc] init];
controller.data = objectDict;
NSString * storyboardName = #"Main";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"SeeInfoVC"];
[self presentViewController:vc animated:YES completion:nil];
In my ViewController.h I have:
#interface SeeCardVC : UIViewController
{
NSDictionary *data;
}
#property (nonatomic, retain)NSDictionary *data;
#end
And then I'm trying to log data in ViewController.m:
#implementation SeeCardVC
#synthesize data;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
NSLog(#"Info: %#", data);
}
But it only gives me null :(
What am I doing wrong?
Let's see what your code is doing here:
// Create new controller, assign objectDict to data property
SeeInfoVC *controller = [[SeeInfoVC alloc] init];
controller.data = objectDict;
//Get Storyboard name
NSString * storyboardName = #"Main";
//Get Storyboard (BTW, you can do this with self.storyboard)
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
//Instantiate NEW controller
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"SeeInfoVC"];
//Present NEW controller
[self presentViewController:vc animated:YES completion:nil];
You created a controller and assigned data to it, and then didn't use it anymore, instead you created a new one from the storyboard, you didn't add the data and presented it.
Basically, you created two, set data to one and presented the other one.
See the problem?
Hello I'm using this library to show my PopOver which contain tableView with searchBar.
The problem is that one user try to select row from the tableView instead dismissing the popOver and displaying the slected row in hole screen I got this :
.
I've tried to use [self.parentViewController.navigationController ...] to push my view but didn't worked.
This is my popOver code (in MainVC.h):
-(IBAction)showPopoverSearch:(id)sender{
UIBarButtonItem *btn = (UIBarButtonItem *) sender;
NSInteger width = 600;
NSInteger height = 400;
SearchViewController *searchVC = [self.storyboard instantiateViewControllerWithIdentifier:#"searchView"];
searchVC.modalInPopover = NO;
UINavigationController* contentViewController = [[UINavigationController alloc] initWithRootViewController:searchVC];
popoverController = [[WYPopoverController alloc] initWithContentViewController:contentViewController];
popoverController.delegate = self;
//popoverController.passthroughViews = #[btn];
popoverController.popoverContentSize = CGSizeMake(width, height);
popoverController.popoverLayoutMargins = UIEdgeInsetsMake(10, 10, 10, 10);
popoverController.wantsDefaultContentAppearance = YES;
[popoverController presentPopoverFromBarButtonItem:btn permittedArrowDirections:WYPopoverArrowDirectionAny animated:YES];
}
And this is the didSelctRow method (SearchViewController.m) :
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main"bundle:nil];
PostReaderViewController *postReaderView =
(PostReaderViewController *)
[storyboard instantiateViewControllerWithIdentifier:#"postReader"];
postReaderView.thePost = [_postsArray objectAtIndex:indexPath.row];
// if ([self.parentViewController.po .popoverController isPopoverVisible])
// [popoverController dismissPopoverAnimated:YES];
[self.navigationController pushViewController:postReaderView animated:YES];
}
To solve this issue I've passed the Navigation controller and popoverController from The parent View MainVC.h to child controller SearchViewController.h and then use those vars to dismiss my PopOvercontroller and push the new VC. Code snippet :
SearchView
#interface SearchViewController : UIViewController
#property (strong, nonatomic) WYPopoverController *parentPopoverVC;
#property (strong, nonatomic) UINavigationController *parentNavigationController;
#end
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
...
[self.parentPopoverVC dismissPopoverAnimated:YES];
[self.parentNavigationController pushViewController:postReaderView animated:YES];
}
MainVC.h
-(IBAction)showPopoverSearch:(id)sender{
SearchViewController *searchVC = [self.storyboard instantiateViewControllerWithIdentifier:#"searchView"];
[searchVC setParentPopoverVC:popoverController];
[searchVC setParentNavigationController:self.navigationController];
[popoverController presentPopoverFromBarButtonItem:btn permittedArrowDirections:WYPopoverArrowDirectionAny animated:YES];
}
I was trying to pass data between an UITableViewController which is showed with:
SeleccionBundesligaViewController *seleccionBundesligaVC = [[SeleccionBundesligaViewController alloc]initWithStyle:UITableViewStylePlain];
seleccionBundesligaVC.title = #"1.Bundesliga";
[self.navigationController pushViewController:seleccionBundesligaVC animated:YES];
and when I select a row it's closed by:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *dic = [equipos objectAtIndex:indexPath.row];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:[NSBundle mainBundle]];
InformacionPartidaViewController *infoPartidaVC = [storyboard instantiateViewControllerWithIdentifier:#"infoPartidaVC"];
[self.navigationController popViewControllerAnimated:YES];
[infoPartidaVC.labelNombreEquipo setText:[dic objectForKey:#"nombre"]];
}
But when I select the row, it doesn't pass data to 'infoPartidaVC'.
Your best bet is to create a property in your SeleccionBundesligaViewController's .h file:
#property (weak, nonatomic) InformacionPartidaViewController *infoPartidaVC;
When you create your UITableViewController and before you push it, add the reference:
SeleccionBundesligaViewController *seleccionBundesligaVC = [[SeleccionBundesligaViewController alloc]initWithStyle:UITableViewStylePlain];
seleccionBundesligaVC.title = #"1.Bundesliga";
seleccionBundesligaVC.infoPartidaVC = self;
[self.navigationController pushViewController:seleccionBundesligaVC animated:YES];
Then, in your didSelectRowAtIndexPath in your UITableViewController:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *dic = [equipos objectAtIndex:indexPath.row];
[self.navigationController popViewControllerAnimated:YES];
[self.infoPartidaVC.labelNombreEquipo setText:[dic objectForKey:#"nombre"]];
}
I think your problem is that you are setting the text of the label before the label is shown.
have a look at this question asked answered by me
I am developing an app in which there are three different tables and single UiView which contains label. I want to display name of that selected table-view cell name set it to the label.
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
AppDelegate * appdelegate=(AppDelegate *)[[UIApplication sharedApplication]delegate];
if(appdelegate.btn1)
{
appdelegate.selectId=indexPath.row;
NSLog(#"select Id %d",appdelegate.selectId);
}
else if(appdelegate.btn2)
{
appdelegate.selectId=indexPath.row;
NSLog(#"select Id %d",appdelegate.selectId);
}
else if(appdelegate.btn3)
{
appdelegate.selectId=indexPath.row;
NSLog(#"select Id %d",appdelegate.selectId);
}
NSString * str=[appdelegate.name objectAtIndex:indexPath.row];
NSString * str1=[appdelegate.iname objectAtIndex:indexPath.row];
NSString * str2=[appdelegate.bname objectAtIndex:indexPath.row];
DetailViewController * dvc=[[DetailViewController alloc]initWithTrick:str andOtherString:str1 andOtherString:str2];
[self.navigationController pushViewController:dvc animated:YES];
}
And Accessing That cell Name into init method.
-(id)initWithTrick:(NSString *)name_ andOtherString:(NSString *)name2_ andOtherString:(NSString *)name3_;
{
if (self)
{
self.trickname=name_;
self.trickname2=name2_;
self.trickname3=name3_;
}
return self;
}
Here trickname,trickname2,trickname3 are the NSString.
I have tried this code but not work for me.
please help me out this.
-(id)initWithTrick:(NSString *)name_ andOtherString:(NSString *)name2_ andOtherString:(NSString *)name3_;
{
self =[super init];
if (self)
{
self.trickname=name_;
self.trickname2=name2_;
self.trickname3=name3_;
}
return self;
}
try this this may help you. your self object not be initialized so the values are not being set in the string.
You can do this alternatively :
Make three property strings in DetailViewController.h class as :
#property (strong, nonatomic) NSString *name1;
#property (strong, nonatomic) NSString *name2;
#property (strong, nonatomic) NSString *name3;
and then syntehsize these in DetailViewController.m class as :
#synthesize name1,name2,name3;
and then access these in tableview delegate didselectrow as
DetailViewController * dvc=[[DetailViewController alloc]initWithTrick:str andOtherString:str1 andOtherString:str2];
dvc.name1= str;
dvc.name2= str1;
dvc.name3= str2;
[self.navigationController pushViewController:dvc animated:YES];
and then access them in your init method.
Hope it helps you.
Leave this all and do like this for passing value to Detailview
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//do what you did that app delegate thing
//now we will pass value which you got from doing stuff above
//Initialize the detail view controller and display it.
DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:[NSBundle mainBundle]];
// i have just put DetailViewController here as nibname you give name of your detailviewcontrollers XIB
dvController.trickname = string1;
dvController.trickname2 = string2;
dvController.trickname3 =string3;
// you are passing values of string 1 2 and 3 to detail view controller string trickname, trickname2 and 3
[self.navigationController pushViewController:dvController animated:YES];
[dvController release];
}
NOTE: trickname,trickname2,trickname3 need to be declared in detail view controller in .h file
I solve my issue now.
Declare that string in table view controller
{
NSString * str;
NSString * str1;
NSString * str2;
}
#property(strong,nonatomic)NSString * str;
#property(strong,nonatomic)NSString * str1;
#property(strong,nonatomic)NSString * str2;
synthesize in .m of table view controller.
#synthesize str,str1,str2;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
AppDelegate * appdelegate=(AppDelegate *)[[UIApplication sharedApplication]delegate];
if(appdelegate.btn1)
{
appdelegate.selectId=indexPath.row;
NSLog(#"select Id %d",appdelegate.selectId);
str=[appdelegate.name objectAtIndex:indexPath.row];
}
else if(appdelegate.btn2)
{
appdelegate.selectId=indexPath.row;
NSLog(#"select Id %d",appdelegate.selectId);
str1=[appdelegate.iname objectAtIndex:indexPath.row];
}
else if(appdelegate.btn3)
{
appdelegate.selectId=indexPath.row;
NSLog(#"select Id %d",appdelegate.selectId);
str2=[appdelegate.bname objectAtIndex:indexPath.row];
}
DetailViewController * dvc=[[DetailViewController alloc]initWithTrick:str andOtherString:str1 andOtherString:str2];
dvc.trickname=str;
dvc.trickname2=str1;
dvc.trickname3=str2;
NSLog(#"%#",str);
appdelegate.counter=0;
[self.navigationController pushViewController:dvc animated:YES];
}
Then goto Detailview Controller and accessing this 3 strings through init() method of Detailview controller.
1st define that init method in DetailVewController.h
-(id)initWithTrick:(NSString *)name_ andOtherString:(NSString *)name2_ andOtherString:(NSString *)name3_;
#property(nonatomic,retain)NSString * trickname;
#property(nonatomic,retain)NSString * trickname2;
#property(nonatomic,retain)NSString * trickname3;
DetailViewController.m
#synthesize trickname;
#synthesize trickname2;
#synthesize trickname3;
-(id)initWithTrick:(NSString *)name_ andOtherString:(NSString *)name2_ andOtherString:(NSString *)name3_;
{
self=[super init];
if (self)
{
self.trickname=name_;
self.trickname2=name2_;
self.trickname3=name3_;
}
return self;
}
I'm trying to create an iPad application with a similar user interface to Apple's Mail application, i.e:
RootView controller (table view) on the left hand side of the split view for navigation with a multiple view hierarchy. When a table cell is selected a new table view is pushed on the left hand side
The new view on the left side can update the detail view.
I can accomplish both tasks, but not together.
I mean I can make a multi-level table view in the RootController.
Or I can make a single-level table view in the RootController which can update the detailViewController.
Can anyone tell me how to make a multi-level table in the RootController which can update a detailViewController?
There is more source code at the link but below is the method in which I presume I have to declare a new detailViewController (which has to be put in the UISplitViewController):
- (void)tableView:(UITableView *)TableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *dictionary = [self.tableDataSource objectAtIndex:indexPath.row];
//Get the children of the present item.
NSArray *Children = [dictionary objectForKey:#"Children"];
//
if([Children count] == 0) {
/*
Create and configure a new detail view controller appropriate for the selection.
*/
NSUInteger row = indexPath.row;
UIViewController <SubstitutableDetailViewController> *detailViewController = nil;
if (row == 0) {
FirstDetailViewController *newDetailViewController = [[FirstDetailViewController alloc]initWithNibName:#"FirstDetailView" bundle:nil];
detailViewController = newDetailViewController;
}
if (row == 1) {
SecondDetailViewController *newDetailViewController = [[SecondDetailViewController alloc]initWithNibName:#"SecondDetailView" bundle:nil];
detailViewController = newDetailViewController;
}
// Update the split view controller's view controllers array.
NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, detailViewController, nil];
splitViewController.viewControllers = viewControllers//nothing happens.....
[viewControllers release];//
}
else {
//Prepare to tableview.
RootViewController *rvController = [[RootViewController alloc]initWithNibName:#"RootViewController" bundle:[NSBundle mainBundle]];
//Increment the Current View
rvController.current_level += 1;
//Set the title;
rvController.current_title = [dictionary objectForKey:#"Title"];
//Push the new table view on the stack
[self.navigationController pushViewController:rvController animated:YES];
rvController.tableDataSource = Children;
[rvController.tableView reloadData]; //without this instrucion,items won't be loaded inside the second level of the table
[rvController release];
}
}
Sorry, but I cannot post my source code as it contains sensitive information. When I have more time available I will create a separate project and upload the code somewhere.
Here are extracts of how I have done it so far (I welcome any feedback).
The RootViewController - Note I have 4 sections in my root table.
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// Detail view logic
NSUInteger section = indexPath.section;
UIViewController <SubstitutableDetailViewController> *detailViewController = nil;
if (section == 2) {
ProductSearchDetailView *viewController = [[ProductSearchDetailView alloc] initWithNibName:#"ProductSearchDetailView" bundle:nil];
detailViewController = viewController;
//[viewController release];
}
else {
DetailViewController *defaultDetailViewController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
detailViewController = defaultDetailViewController;
//[defaultDetailViewController release];
}
// Navigation logic
switch (section) {
case 0:
{
break;
}
case 1:
{
break;
}
case 2:
{
// new Navigation view
ProductSearchViewController *viewController = [[ProductSearchViewController alloc] initWithNibName:#"ProductSearchViewController" bundle:nil];
viewController.navigationItem.backBarButtonItem.title = #"Back";
[self.navigationController pushViewController:viewController animated:YES];
[viewController release];
break;
}
case 3:
{
StoreLocatorNavController *viewController = [[StoreLocatorNavController alloc] initWithNibName:#"StoreLocatorNavController" bundle:nil];
viewController.navigationItem.backBarButtonItem.title = #"Back";
[self.navigationController pushViewController:viewController animated:YES];
[viewController release];
break;
}
}
// Update the split view controller's view controllers array.
NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, detailViewController, nil];
splitViewController.viewControllers = viewControllers;
[viewControllers release];
// Dismiss the popover if it's present.
if (popoverController != nil) {
[popoverController dismissPopoverAnimated:YES];
}
// Configure the new view controller's popover button (after the view has been displayed and its toolbar/navigation bar has been created).
if (rootPopoverButtonItem != nil) {
[detailViewController showRootPopoverButtonItem:self.rootPopoverButtonItem];
}
[detailViewController release];
}
NSNotificationCenter part
Add this to ProductSearchViewController:
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *itemAtIndex = (NSDictionary *)[self.productResults objectAtIndex:indexPath.row];
[[NSNotificationCenter defaultCenter] postNotificationName:#"updateProduct" object:itemAtIndex];
}
And finally, add this to ProductSearchDetailViewController:
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(updateTheProductDetails:) name:#"updateProduct" object:nil];
}
- (void)updateTheProductDetails:(NSNotification *)notification {
NSDictionary *productDictionary = [NSDictionary dictionaryWithDictionary:[notification object]];
// product name
_productName.text = [productDictionary objectForKey:#"ProductDescription"];
}
Hope it helps!