.h
#interface DetailViewController : UIViewController
{
IBOutlet UILabel *sname;
IBOutlet UIImageView *sImage;
}
#property (strong, nonatomic)id titletwo;
#property (strong, nonatomic)id Viewimage;
.m
#interface DetailViewController ()
#end
#implementation DetailViewController
{
[super viewDidLoad];
UIImage* theImage = [UIImage imageNamed:[self.Viewimage description]];
sImage.image = theImage;
sname.text = [self.titletwo description];
}
Viewcontroller.m
- (void)tableViewUITableView *)tableView didDeselectRowAtIndexPathNSIndexPath *)indexPath
{
NSDictionary *tmpDict = [myObject objectAtIndex:indexPath.row];
DetailViewController *view2 = [[[DetailViewController alloc] initWithNibName:nil bundle:nil] autorelease];
view2.Viewimage = [tmpDict objectForKey:thumbnail];
view2.titletwo = [tmpDict objectForKey:name];
[self.navigationController pushViewController:view2 animated:YES];
}
my title can get a data and show it! but the image can 't what can i do?
Thee problem is with following line of code
DetailViewController *view2 = [[[DetailViewController alloc] initWithNibName:nil bundle:nil] autorelease];
as you are initialising DetailViewController with nib pointed to nil.
Specified nib name here
DetailViewController *view2 = [[[DetailViewController alloc] initWithNibName:#"SPECIFIED NIB NAME HERE" bundle:nil] autorelease];
First, you should consider using only ARC in your program. In .h you're defining your property as:
#property (strong, nonatomic)id titletwo;
using stong but then in ViewController you're using autorelease:
DetailViewController *view2 = [[[DetailViewController alloc] initWithNibName:nil bundle:nil] autorelease];
Second: things to check: put a breakpoint at view2.Viewimage = [tmpDict objectForKey:thumbnail];and print the content of [tmpDict objectForKey:thumbnail]writing in lldb window:
po [tmpDict objectForKey:thumbnail]
That will print the value returned. If it's nil, there's no key thumbnail in that object. Maybe you misspell that thumbnail constant.
Third: self.ViewImage looks like a UIImage, but you're using description here. Are you sure you know which type is everything? You're using ids...
Related
I have a UILabel in interface builder that I've connected to a property, but it's staying nil through the viewDidLoad on that view controller. I've been stepping through and as soon as the DetailViewController is initialized, the label property is there but it is nil and it never seems to be initialized.
It was working until I switched from using segues to doing pushViewController on the navigation controller.
// DetailsViewController.h
#import <UIKit/UIKit.h>
#import "TLitem.h"
#interface DetailsViewController : UIViewController
#property (nonatomic, strong) TLitem *entry;
#property (weak, nonatomic) IBOutlet UILabel *entryLabel;
#end
Then in a table view in another view controller:
// EntryListViewController.m
DetailsViewController *details = [[DetailsViewController alloc] init];
[details setEntry:entry];
[self.navigationController pushViewController:details animated:YES];
And in the viewDidLoad:
// DetailsViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
[self.view setBackgroundColor:[UIColor yellowColor]];
TLitem *entry = [self entry];
UILabel *label = [self entryLabel];
label.text = [entry valueForKey:#"text"];
[[DetailsViewController alloc] init] is not loading the view controller from the storyboard. It creates a new DetailsViewController, but nothing from IB will be connected. Look into -instantiateViewControllerWithIdentifier:
It will look something like
DetailsViewController *details = [self.storyboard instantiateViewControllerWithIdentifier:#"Some Storyboard Identifier You Create"];
details.entry = entry;
[self.navigationController pushViewController:details animated:YES];
I need enlightenment with my view controllers. The first view controller has a UILabel and a UIButton. The UIButton leads to the second view controller.
The second view controller is a UITableView. Everything in this view is done programmatically including the UINavigationBar, UINavigationItem, and the UIBarButtonItem. It has NO UINavigationController.
So once a user selects a currency from the list, it should update the UILabel in the first view controller. But it won't.
first view controller .h:
#import <UIKit/UIKit.h>
#import "CurrencyListViewController.h"
#interface InformationViewController : UIViewController <CurrencyListViewControllerDelegate>
#property (nonatomic, retain) IBOutlet UILabel *currencyLabel;
- (IBAction)currencyButton;
#end
first view controller .m:
- (void)viewDidLoad
{
[super viewDidLoad];
[self createCurrencyButton];
[self createAcceptDeclineButton];
[self createCurrencyLabel];
}
- (IBAction)currencyButton
{
CurrencyListViewController *currencyView = [[CurrencyListViewController alloc] initWithNibName:#"CurrencyListViewController" bundle:nil];
currencyView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
currencyView.delegate = self;
[self presentViewController:currencyView animated:YES completion:nil];
}
- (void)createCurrencyLabel
{
currencyLabel = [[UILabel alloc] initWithFrame:CGRectMake(100.0, 100.0, 120.0, 40.0)];
currencyLabel.hidden = NO;
currencyLabel.textColor = [UIColor whiteColor];
currencyLabel.textAlignment = NSTextAlignmentCenter;
[currencyLabel setEnabled:NO];
[self.view addSubview:currencyLabel];
}
- (void)currencySelected: (NSString *)currencySelected
{
currencyLabel.text = [NSString stringWithFormat:#"%#", currencySelected];
NSLog(#"Current currency is %#", currencyLabel.text);
}
second view controller .h:
#import <UIKit/UIKit.h>
#protocol CurrencyListViewControllerDelegate <NSObject>
- (void)currencySelected: (NSString *)currencySelected;
#end
#interface CurrencyListViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
id<CurrencyListViewControllerDelegate> delegate;
}
#property (nonatomic, retain) UITableView *tableView;
#property (nonatomic, assign) id delegate;
#end
second view controller .m:
- (void)viewDidLoad
{
[super viewDidLoad];
UINavigationBar *navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 44.0)];
UINavigationItem *navigationItem = [[UINavigationItem alloc] initWithTitle:#"Currency"];
UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithTitle: #"Cancel"
style:UIBarButtonItemStylePlain
target:self
action:#selector(cancelButtonPressed:)];
navigationItem.rightBarButtonItem = barItem;
UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0.0, 44.0, self.view.frame.size.width, self.view.frame.size.height - navigationBar.frame.size.height) style:UITableViewStylePlain];
self.tableView = tableView;
[navigationBar pushNavigationItem:navigationItem animated:NO];
[self.view addSubview:tableView];
[self.view addSubview:navigationBar];
[self showCurrencies];
self.tableView.dataSource = self;
self.tableView.delegate = self;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [arrayOfCurrencies objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
InformationViewController *informationViewController = [[InformationViewController alloc] init];
if ([_delegate respondsToSelector:#selector(currencySelected:)]) {
informationViewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[_delegate currencySelected:[arrayOfCurrencies objectAtIndex:indexPath.row]];
NSLog(#"The user selects %#", [arrayOfCurrencies objectAtIndex:indexPath.row]);
}
[self presentViewController:informationViewController animated:YES completion:nil];
}
I am able to output:
2013-06-05 00:16:58.731 Testing[7056:c07] Current currency is AOA: Angolan Kwanza
2013-06-04 19:08:27.222 Testing[3613:c07] 2013-06-05 00:16:58.732 Testing[7056:c07] The user selects AOA: Angolan Kwanza
But the UILabel in my first view controller will NOT.
Why are presenting informationViewController again? dismiss the Current ViewController, which is CurrencyListViewController and do the currencySelected function
Should look like this:
[self dismissModalViewControllerAnimated:YES];
[_delegate currencySelected:[arrayOfCurrencies objectAtIndex:indexPath.row]];
I'm trying to create a SplitViewController view but I get the following warning:
Property splitViewController requires a method setSplitViewController to be defined -use #Synthesize,#dynamic or provide a method implementation in this class implement.
Here is the code
///AppDelegate.h
#class ViewController;
#class DetailViewController;
#interface AppDelegate : UIResponder <UIApplicationDelegate, UISplitViewControllerDelegate>
{
UISplitViewController *splitViewController;
ViewController *viewcontroller;
DetailViewController *detailViewController;
}
#property (nonatomic,retain) UIWindow *window;
#property (nonatomic,retain) DetailViewController *detailViewController;
#property(nonatomic,retain) UISplitViewController *splitViewController;
#property (nonatomic,retain) ViewController *viewController;
#end
///AppDelegate.m"
#import "ViewController.h"
#import "DetailViewController.h"
#implementation AppDelegate
#synthesize window = _window;
#synthesize viewController = _viewController;
#synthesize splitviewController;
#synthesize detailViewController;
- (void)dealloc
{
[_window release];
[_viewController release];
[super dealloc];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
ViewController *rootViewController = [[ViewController alloc] initWithStyle:UITableViewStylePlain];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
rootViewController.detailViewController = detailViewController;
splitViewController = [[UISplitViewController alloc] init];
splitViewController.viewControllers = [NSArray arrayWithObjects:navigationController, detailViewController, nil];
splitViewController.delegate = detailViewController;
[self.window makeKeyAndVisible];
return YES;
}
///ViewController.h
#import <UIKit/UIKit.h>
#class DetailViewController;
#interface ViewController : UITableViewController{
DetailViewController *detailViewController;
NSMutableArray *phone;
}
#property (nonatomic,retain)IBOutlet DetailViewController *detailViewController;
#property (nonatomic,retain) NSMutableArray *phone;
#end
///ViewController.m
#import "ViewController.h"
#import "DetailViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize detailViewController,phone;
- (CGSize)contentSizeForViewInPopoverView {
return CGSizeMake(320, 600);
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.phone = [[NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"phone" ofType:#"plist"]] retain];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)aTableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [phone count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CellIdentifier";
// Dequeue or create a cell of the appropriate type.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryNone;
}
// Configure the cell.
cell.textLabel.text = [self.phone objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
/*
When a row is selected, set the detail view controller's detail item to the item associated with the selected row.
*/
detailViewController.detailItem = [self.phone objectAtIndex:indexPath.row];
}
- (void)dealloc {
[detailViewController release];
[super dealloc];
}
#end
In ur code, you haven't synthesized your splitViewController property. Since You have not synthesized it the property, the compiler is issuing a warning asking u to either synthesize the property so that it can generate setters and getters automatically for your convinienvce (You can use the generated setters and getters using . notation as in self.splitViewController so synthesize it as
#synthesize splitViewController = _splitViewController
or
implement your own custom setter and getter as
//setter
- (void)setSplitViewController:(UISplitViewController*)splitViewController_ {
//assuming your property has retain identifier
if (splitViewController != splitViewController_) {
[splitViewController release];
splitViewController = [splitViewController_ retain];
}
}
//getter
- (UISplitViewController*)splitViewController {
return splitViewController;
}
or
declaring the property as dynamic using #dynamic splitViewController . This means that the setter and getter for the property will be provided from somewhere else.
EDIT:
replacedidFinishLaunchingWithOptions method in appDelegate.m with the following:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
_viewController = [[ViewController alloc] initWithNibName:#"ViewController's nib name" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:_viewController];
detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
rootViewController.detailViewController = detailViewController;
splitViewController = [[UISplitViewController alloc] init];
splitViewController.viewControllers = [NSArray arrayWithObjects:navigationController, detailViewController, nil];
splitViewController.delegate = detailViewController;
self.window.rootViewController = splitViewController;
return YES;
}
also edit the dealloc:
- (void)dealloc
{
[_window release];
[_viewController release];
[splitViewController release];
[detailViewController release];
[super dealloc];
}
And in viewController viewDidLoad replace self.phones line with this
self.phone = [[NSArray arrayWithObjects:#"Cell ONE",#"Cell TWO",#"Cell THREE",#"Cell FOUR",#"Cell FIVE",#"Cell SIX", nil];
this is just for testing that the array part is loading properly..so that you can see the cells if they are getting created. put a break point in cellForRowAtIndexPath method and see if its getting called
and then finally in didSelect see if the detailItem iVar is not nil.
And Yes, check the NIB names properly before loading them, and also that all outlets in the NIB are properly connected.
Cheers and Have fun.
The problem is you misspelled splitViewController in your #synthesize statement -- you didn't capitalize the v.
You wouldn't run into this problem if you did it the easy way. There's no need for either the instance variables or the #synthesize statements any more -- you get both automatically when create the property.
In your case add #synthesize splitViewController = _splitViewController; and detailViewController = _ detailViewController;
Here is useful code for, how can i add UISplitViewController.
/// AppDelegate.h file
#import <UIKit/UIKit.h>
#import "MasterViewController.h"
#import "DetailViewController.h"
#interface AppDelegate : UIResponder <UIApplicationDelegate, UISplitViewControllerDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (nonatomic, strong) UISplitViewController *splitViewController;
#property (nonatomic, strong) MasterViewController *masterVC;
#property (nonatomic, strong) DetailViewController *detailVC;
#property (nonatomic, strong) UINavigationController *mvcNavCon;
#property (nonatomic, strong) UINavigationController *dvcNavCon;
#end
/// AppDelegate.m File
#import "AppDelegate.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
self.masterVC = [[MasterViewController alloc] init];
self.mvcNavCon = [[UINavigationController alloc] initWithRootViewController:self.masterVC];
self.detailVC = [[DetailViewController alloc] init];
self.dvcNavCon = [[UINavigationController alloc] initWithRootViewController:self.detailVC];
self.splitViewController = [[UISplitViewController alloc] init];
self.splitViewController.delegate = self;
self.splitViewController.viewControllers = [NSArray arrayWithObjects:self.mvcNavCon, self.dvcNavCon,nil];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = self.splitViewController;
[self.window makeKeyAndVisible];
return YES;
}
So I am trying to display a UITableView inside a UIPopoverController using the piece of code shown below
vc = [[ActionsViewController alloc] init];
initWithContentViewController:vc];
actionsController = [[UIPopoverController alloc] initWithContentViewController:vc];
actionsController.delegate = self;
NSLog(#"Try to sho it ");
[actionsController presentPopoverFromBarButtonItem:(UIBarButtonItem*)sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
And this is ActionsViewController.m which is a subclass of UITableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSMutableArray* list = [[NSMutableArray alloc] initWithCapacity:4];
self.actionList = list;
self.clearsSelectionOnViewWillAppear = NO;
self.contentSizeForViewInPopover = CGSizeMake(320.0, 400.0);
[self.actionList addObject:#"Print as book"];
[self.actionList addObject:#"Print page"];
[self.actionList addObject:#"Save Page"];
[self.actionList addObject:#"Share"];
}
- (int)numberOfSectionsInTableView:(UITableView *)tableView
{
NSLog(#"in number of section");
return 1;
}
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSString* lab = [self.actionList objectAtIndex:indexPath.row];
NSLog(#"here in there");
cell.textLabel.text = lab;
return cell;
}
- (NSInteger)numberOfRowsInSection:(NSInteger)section
{
return [self.actionList count];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (self.delegate != nil) {
[self.delegate actionSelected:indexPath.row];
}
}
The corresponding .h file
#import <UIKit/UIKit.h>
#protocol KLActionsViewControllerDelegate
- (void)actionSelected:(NSInteger)index;
#end
#interface KLActionsViewController : UITableViewController <UITableViewDataSource,UITableViewDelegate>
#property (nonatomic, retain) NSMutableArray* actionList;
#property (nonatomic, assign) id<KLActionsViewControllerDelegate> delegate;
#end
Also, I don't think the functions cellForRowAtIndexPath and numberOfSectionsInTableView are getting called because I don't see any console output.
EDIT: This is what I see in the popover
:
In viewDidLoad I added self.tableView = [[UITableView alloc] init]
I guess, the problem would be in that line:
vc = [[ActionsViewController alloc] init];
if you have a NIB file, you should load the UIViewController with using it.
vc = [[ActionsViewController alloc] initWithNibName:#"ActionViewController" bundle:nil];
// the NibName must be the exact name of XIB file without extension.
OR/AND
you should set the popoverContentSize:
[actionController setPopoverContentSize:vc.view.frame.size];
I hope it helps a bit for you.
UPDATE:
it seems it is not an UIPopoverController problem, just a simple UITableViewController delegate issue.
in that line:
actionsController.delegate = self;
you should set that class as delegate which implements the UITableViewDelegate. basically it is the UITableViewController itself like
actionsController.delegate = actionController;
therefore you should not replace this in that case if you haven't implemented the delegate callback methods in the self which the new delegate class is. you simple steal the chance from the class which was really delegated to answer the callbacks, and in you new delegate class you don't answer the callbacks.
this would be the reason why you are seeing the empty table, without the datas.
You need to load the table view via (last line of viewdidload :
[self.tableView reloadData];
that will trigger the table view methods to action. Put a breakpoint in the various tableview methods particularly in -
(NSInteger)numberOfRowsInSection:(NSInteger)section
{
return [self.actionList count];
}
If this does not get called your tableview is not loaded.
UITableViewController is implicit set datasource and delegate, there is no need to set explicitly datasource and delegate.
Remove UITableViewDataSource,UITableViewDelegate from .h file
#import <UIKit/UIKit.h>
#protocol KLActionsViewControllerDelegate
- (void)actionSelected:(NSInteger)index;
#end
#interface KLActionsViewController : UITableViewController
#property (nonatomic, retain) NSMutableArray* actionList;
#property (nonatomic, assign) id<KLActionsViewControllerDelegate> delegate;
#end
and also remove this line **actionsController.delegate = self;
vc = [[ActionsViewController alloc] init];
actionsController = [[UIPopoverController alloc] initWithContentViewController:vc];
[actionsController presentPopoverFromBarButtonItem:(UIBarButtonItem*)sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
I have a split view controller for iPad with a drill-down table on the left. I am able to populate the tables with a drill-down without issue but I cannot seem to get the item I clicked within the UITableView on the left side to show up in detailDescriptionLabel on the right side.
I have the following code in my ProductViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSLog(#"Row clicked: %i", indexPath.row);
if (_delegate != nil) {
Product *product = (Product *) [_products objectAtIndex:indexPath.row];
[_delegate productSelectionChanged:product];
}
DetailedVC *detailView = [[DetailedVC alloc] initWithNibName:#"DetailedVC" bundle:[NSBundle mainBundle]];
NSLog(#"User clicked on: %#", [NSString stringWithFormat:#"%d",indexPath.row]);
detailView.detailDescriptionLabel.text = [NSString stringWithFormat:#"%d",indexPath.row];
[self.navigationController pushViewController:detailView animated:YES];
}
What happens here is I push the DetailedVC into the left side where my table view is and what I really want to do is see the row clicked updated in my detailed view on the right. I am able to see in the Log window that I clicked on a certain index so I know I am capturing the click event and getting a value.
Inside my DetailedVC.m I have the following code to update this label.
- (void)viewDidLoad
{
[super viewDidLoad];
[self configureView];
}
- (void) configureView {
if (self.detailItem) {
self.detailDescriptionLabel.text = [self.detailItem description];
NSLog(#"Item: %#", [self.detailItem description]);
}
}
If I edit the viewDidLoad I get a (null) for the [self.detailItem description]
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"Detail description label: %#", [self.detailItem description]);
}
ProductViewController.h
#interface ProductViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
NSMutableArray *_products;
UITableView *_productsTableView;
id<ProductSelectionDelegate> _delegate;
}
#property (nonatomic, strong) IBOutlet UITableView *productsTableView;
#property (nonatomic, retain) NSMutableArray *products;
#property (nonatomic, assign) id<ProductSelectionDelegate> delegate;
#end
AppDelegate.h
#class ProductViewController;
#class DetailedVC;
#interface TabAndSplitAppAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
UIWindow *window;
UITabBarController *tabBarController;
ProductViewController *_productViewController;
DetailedVC *_detailedViewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#property (nonatomic, retain) IBOutlet ProductViewController *productViewController;
#property (nonatomic, retain) IBOutlet DetailedVC *detailedViewController;
#end
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSMutableArray *products = [NSMutableArray array];
[products addObject:[[Product alloc] initWithName:#"Product 1 Name" desc:#"Product 1 Description"]];
_detailedViewController.product = [products objectAtIndex:0];
// Override point for customization after app launch.
//create split view controller
RootVC *rvc=[[RootVC alloc] init];
rvc.title=#"Root VC";
DetailedVC *dvc=[[DetailedVC alloc] init];
dvc.title=#"Detailed VC";
_productViewController.delegate = _detailedViewController;
MySplitViewController *msc = [[MySplitViewController alloc] initwithLeftVC:rvc rightVC:dvc];
msc.title=#"First";
//create a temporary VC to show in second tab
SecondViewController *vc2 = [[SecondViewController alloc] init];
vc2.title=#"Second";
//make an array containing these two view controllers
NSArray *viewControllers = [NSArray arrayWithObjects:msc,vc2,nil];
[tabBarController setViewControllers:viewControllers];
tabBarController.view.backgroundColor=[UIColor blackColor];
for(UITabBarItem*t in tabBarController.tabBar.items)
{
t.image=[UIImage imageNamed:#"icon.png"];
t.badgeValue=[NSString stringWithFormat:#"%d",([tabBarController.tabBar.items indexOfObject:t]+1)];
}
//the views are retained their new owners, so we can release
[rvc release];
[dvc release];
[msc release];
[vc2 release];
// Add the tab bar controller's current view as a subview of the window
[self.window addSubview:tabBarController.view];
[self.window makeKeyAndVisible];
return YES;
}
MySplitViewController.h
#import <UIKit/UIKit.h>
#interface MySplitViewController : UIViewController
{
UINavigationController *leftController;
UINavigationController *rightController;
}
#property (nonatomic, retain) UINavigationController *leftController;
#property (nonatomic, retain) UINavigationController *rightController;
- (void)layoutViews:(UIInterfaceOrientation)orientation initialVerticalOffset:(float)offset;
- (MySplitViewController*) initwithLeftVC:(UIViewController*)leftvc rightVC:(UIViewController*)rightvc;
#end
MySplitViewController.m
- (MySplitViewController*) initwithLeftVC:(UIViewController*)leftvc rightVC:(UIViewController*)rightvc
{
if(self=[super init])
{
UINavigationController *lnc=[[UINavigationController alloc] initWithRootViewController:leftvc];
lnc.navigationBarHidden=NO;
self.leftController=lnc;
[lnc release];
UINavigationController *rnc=[[UINavigationController alloc] initWithRootViewController:rightvc];
rnc.navigationBarHidden=NO;
self.rightController=rnc;
[rnc release];
}
return self;
}
Product.h
#import <Foundation/Foundation.h>
#interface Product : NSObject {
NSString *_productID;
NSString *_productDescription;
}
#property (nonatomic, copy) NSString *productID;
#property (nonatomic, copy) NSString *productDescription;
- (Product *)initWithName:(NSString *)productID desc:(NSString *)productDescription;
#end
Product.m
#import "Product.h"
#implementation Product
#synthesize productID = _productID;
#synthesize productDescription = _productDescription;
- (Product *)initWithName:(NSString *)productID desc:(NSString *)productDescription {
if ((self = [super init])) {
self.productID = productID;
self.productDescription = productDescription;
}
return self;
}
#end
Ok, please try this in ProductViewController:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSLog(#"Row clicked: %i", indexPath.row);
Product *product = (Product *) [_products objectAtIndex:indexPath.row];
NSLog(#"Product: %#", product);
TabAndSplitAppAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSLog(#"appDelegate: %#", appDelegate);
UITabBarController *tbc = appDelegate.tabBarController;
NSLog(#"tbc: %#", tbc);
MySplitViewController *msvc = tbc.selectedViewController;
NSLog(#"msvc: %#", msvc);
UINavigationController *rnc = msvc.rightController;
NSLog(#"rnc: %#", rnc);
DetailedVC *dvc = rnc.topViewController;
NSLog(#"dvc: %#", dvc);
dvc.detailDescriptionLabel.text = #"We found our DetailedVC";
[dvc productSelectionChanged:product];
}
This code is not an example of how you should structure your program properly. This was just to help me (and you) understand your view controller hierarchy.
The initial idea of notifying a delegate when a product is selected is spot on, it just didn't work in your case because the objects weren't wired up properly. You should try to do that though. In the code you posted, I don't see a location where both the ProductViewControllerand the DetailedVC are both directly visible so that you could just say
productViewControllerInstance.delegate = detailedVCinstance;
The nearest to that is in AppDelegate where you have the RootVC instance rvcthat presumably eventually will create the ProductViewController and the dvc. Maybe you could give the dvcto the rvcso that it can set it as the ProductViewController's delegate when it's created. Good luck!