I have two viewControllers where one of them contains a UILabel and a UIButton, and the other one a UITableView. When the UIButton in the first view is pressed the new ViewController is presented and when a row in the tableview is selected the tableview is dismissed and the UILabel in the first viewController should be updated so its text is the same as the cell name tapped in the tableview.
Code:
In the first Viewcontroller:
- (void)changeTitleWithString:(NSString *)title
{
UILabel* selected_station = [[UILabel alloc ]initWithFrame:CGRectMake(45, 153+45, 231, 20)];
[selected_station setFont:[UIFont systemFontOfSize:16.0]];
selected_station.textAlignment = NSTextAlignmentCenter;
selected_station.text = [NSString stringWithFormat:#"%#", title];
[self.view addSubview:selected_station];
NSLog(#"%#", selected_station);
NSLog(#"%#", title);
}
In second viewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.currentString = [NSString stringWithFormat:#"Cell %d", indexPath.row+1];
NewViewController *viewCOntroller = [[NewViewController alloc] init];
[viewController changeTitleWithString:self.currentString];
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
The changeTitleWithString function is called and the string from tableview is successfully received in the function, but the UILabel won't show up. When I log out the UILabel (selected_station) it's not nil and its text is correct. Why doesn't the string show up on the view?
This does not look like you are referencing back to a previous allocated view controller (NewViewController). Rather you are allocating a new NewViewController.
A better approach might be to create a delegate protocol for the second view controller and make the NewViewController it's delegate --
So create a second view controller with a delegate property.
something like this
#protocol SecondViewControllerDelegate;
#interface SecondViewController : UIViewController
#property (nonatomic, strong) NSString *currentString;
#property (nonatomic, assign) id<SecondViewControllerDelegate>delegate;
#end
//----------------------------------------------------------------------------------
#protocol SecondViewControllerDelegate <NSObject>
#optional
-(void) secondViewController:(SecondViewController*)secondViewController didChangeSelectionText:(NSString *)string;
#end
Now in the implementation of the SecondViewController do something like this
#implementation SecondViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.currentString = [NSString stringWithFormat:#"Cell %ld", indexPath.row+1];
if ([self.delegate respondsToSelector:#selector(secondViewController:didChangeSelectionText:)]) {
[self.delegate secondViewController:self didChangeSelectionText:self.currentString];
}
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
#end
Now in the implementation of the FirstViewController (your NewViewController) do something like this
#implementation FirstViewController
-(void) showSecondController
{
SecondViewController *viewController = [[SecondViewController alloc] init];
[viewController setDelegate:self]; // set this controller as the delegate
// add the rest of the display code here
}
#pragma mark - SecondViewControllerDelegate Methods
-(void) secondViewController:(SecondViewController*)secondViewController didChangeSelectionText:(NSString *)string
{
//change your text here
}
#end
This should be enough to get you pointed in the right direction
In FirstViewController
- (void)changeTitleWithString:(NSString *)title :(UIView *)labelView
{
UILabel* selected_station = [[UILabel alloc ]initWithFrame:CGRectMake(45, 153+45, 231, 20)];
[selected_station setFont:[UIFont systemFontOfSize:16.0]];
selected_station.textAlignment = NSTextAlignmentCenter;
selected_station.text = title;
[labelView addSubview:selected_station];
NSLog(#"%#", selected_station);
NSLog(#"%#", title);
}
InSecondViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.currentString = [NSString stringWithFormat:#"Cell %d", indexPath.row+1];
NewViewController *viewCOntroller = [[NewViewController alloc] init];
[viewController changeTitleWithString:self.currentString:self.view];
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
I hope it helps
Related
I am trying to send data back from one view controller to another. I am doing this based off another Q & A in stack overflow but I still have not go the hang of it.
LocationViewController.h
#import "ViewController.h"
#class LocationViewController;
#protocol LocationViewControllerDelegate <NSObject>
- (void)addItemViewController:(LocationViewController *)controller didFinishEnteringItem:(NSString *)item;
#end
#interface LocationViewController : UIViewController
#property (nonatomic, strong) UILabel *locationLabel;
#property (nonatomic, strong) UITextField *locationField;
#property (nonatomic, strong) NSString *fieldText;
#property (nonatomic, weak) id <LocationViewControllerDelegate> delegate;
- (instancetype) init;
-(void)saveButtonPressed;
#end
LocationViewController.m
#import "LocationViewController.h"
#import "SetScoringTableViewController.h"
#import "GameDetailsTableViewController.h"
#interface LocationViewController ()
#end
#implementation LocationViewController
#synthesize locationField;
#synthesize locationLabel;
#synthesize fieldText;
- (void)viewDidLoad {
[super viewDidLoad];
[self.view setBackgroundColor:[UIColor whiteColor]];
//label
locationLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 100, 1000, 20)];
[locationLabel setText: #"Location:"];
[self.view addSubview:locationLabel];
//text field
locationField = [[UITextField alloc] initWithFrame:CGRectMake(20, 150, 300, 35)];
[locationField setBorderStyle: UITextBorderStyleRoundedRect];
locationField.text = #"Enter Location Here";
[self.view addSubview:locationField];
//save button
UIBarButtonItem *saveButton = [[UIBarButtonItem alloc] initWithTitle: #"Save" style: UIBarButtonItemStylePlain target: self action: selector(saveButtonPressed)];
self.navigationItem.rightBarButtonItem = saveButton;
}
-(void)saveButtonPressed {
locationField.text = locationField.text;
[self.delegate addItemViewController:self didFinishEnteringItem:locationField.text];
NSLog(#"%#", locationField.text);
[self.navigationController popViewControllerAnimated:YES ];
[self performSelector:#selector(saveButtonPressed) withObject:nil afterDelay:0.25];
GameDetailsTabelViewController *gameDetails = [[GameDetailsTableViewController alloc] init];
[gameDetails.tableView reloadData]
}
GameDetailsTableViewController.m:
-(void)addItemViewController:(LocationViewController *)controller didFinishEnteringItem:(NSString *)item {
LocationViewController *locationView = [[LocationViewController alloc]initWithNibName:#"LocationViewController" bundle:nil];
locationView.delegate = self;
[[self navigationController]pushViewController:locationView animated:YES];
item = fieldText;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifer1 = #"GameDetailsLocationCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifer1];
label = (UILabel *)[cell viewWithTag:0];
label.text = [NSString stringWithFormat: #"%#", fieldText];
return cell;
}
}
When I run this I get null for the item. I would like to know why I am getting null on the item which is preventing my from further usage of this program.
I am guessing that you wanna send some info from LocationVC to GameDetailVC.
In that case
LocationViewController.m
-(void)saveButtonPressed {
if([self.delegate respondsToSelector:#selector(addItemViewController:didFinishEnteringItem:)]{
[self.delegate addItemViewController:self didFinishEnteringItem:locationField.text];
}
[self.navigationController popViewControllerAnimated:YES ];
}
GameDetailsTableViewController.m:
-(void)addItemViewController:(LocationViewController *)controller didFinishEnteringItem:(NSString *)item {
//do something with item?
//reload table data?
[self.tableview reloadData];
}
Hope it helps.
check for errors.
Right now I have a kind of pop-up selector so that the user can pick an option on my screen. Please see this sample project to see what I mean.
I'm using the same method as this sample, except that I have three different buttons where the user will select. My problem is that I am using this code:
- (void)itemSelectedatRow:(NSInteger)row
{
NSLog(#"row %lu selected", (unsigned long)row);
[self.selectSeverity setTitle:[self.severityArray objectAtIndex:row] forState:UIControlStateNormal];
[self.selectStatus setTitle:[self.statusArray objectAtIndex:row] forState:UIControlStateNormal];
[self.selectGender setTitle:[self.genderArray objectAtIndex:row] forState:UIControlStateNormal];
}
...and it is changing the name of the button for all three every time the user selects one. So for example, if the user taps the "selectSeverity" button, and chooses the item on row three, the name for the selectStatus and selectGender button will also change to the item on row three on its own corresponding array.
What I need to do is somehow separate this method so the button's title changes only when a row has been selected in its own array: how can I do this?
More information:
I have these tableViews embedded in a Navigation Controller:
statusViewController.m/.h
genderViewController.m/.h
pickerViewController.m/.h (this corresponds to the Severity button)
Each have a delegate with a separate ID, but the same content:
#protocol correspondingViewControllerDelegateHere <NSObject>
#required
- (void)itemSelectedatRow:(NSInteger)row;
#end
#interface correspondingViewControllerHere : UITableViewController
#property (strong, nonatomic) NSArray *correspondingArrayHere;
#property (assign, nonatomic) id<statusViewControllerDelegate> delegateIdHere;
#end
Each have the same content in the .m file as well, but correspond to their own delegates, arrays, etc.
#implementation statusViewController
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.statusData.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"CellIdentifierHere";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = [self.statusData objectAtIndex:indexPath.row];
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if ([self.delegateIdHere respondsToSelector:#selector(itemSelectedatRow:)]) {
[self.delegateIdHere itemSelectedatRow:indexPath.row];
[self dismissViewControllerAnimated:YES completion:nil];
}
}
#end
In manualViewController.h (this is the view where they are implemented) I have declared the delegates.
Lastly, in the file manualViewController.m, I have the following code to implement them:
- (IBAction)showinfo:(id)sender
{
UINavigationController *navigationController = (UINavigationController *)[self.storyboard instantiateViewControllerWithIdentifier:#"pickerVC"];
pickerViewController *tableViewController = (pickerViewController *)[[navigationController viewControllers] objectAtIndex:0];
tableViewController.severityData = self.severityArray;
tableViewController.navigationItem.title = #"Triage Severity Levels";
tableViewController.delegate1 = self;
[self presentViewController:navigationController animated:YES completion:nil];
}
- (IBAction)showStatus:(id)sender {
UINavigationController *navigationController = (UINavigationController *)[self.storyboard instantiateViewControllerWithIdentifier:#"statusVC"];
statusViewController *tableViewController = (statusViewController *)[[navigationController viewControllers] objectAtIndex:0];
tableViewController.statusData = self.statusArray;
tableViewController.navigationItem.title = #"Triage Severity Levels";
tableViewController.delegate3 = self;
[self presentViewController:navigationController animated:YES completion:nil];
}
- (IBAction)showGender:(id)sender {
UINavigationController *navigationController = (UINavigationController *)[self.storyboard instantiateViewControllerWithIdentifier:#"genderVC"];
genderViewController *tableViewController = (genderViewController * [[navigationController viewControllers] objectAtIndex:0];
tableViewController.genderData = self.genderArray;
tableViewController.navigationItem.title = #"Triage Severity Levels";
tableViewController.delegate2 = self;
[self presentViewController:navigationController animated:YES completion:nil];
}
SO as I said before, I think the code lies in the itemSelectedAtRow. Can someone help me separate this method so that the choice of one item does not affect the choice of another item?
Thanks
One solution is to change the protocol to require three different methods
#protocol correspondingViewControllerDelegateHere <NSObject>
#required
- (void)itemSelectedSeverityAtRow:(NSInteger)row;
- (void)itemSelectedStatusAtRow:(NSInteger)row;
- (void)itemSelectedGenderAtRow:(NSInteger)row;
#end
Then implement the three methods in the manualViewController and call the appropriate method from each of the other view controllers.
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 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 am using Apple's MuiltipleDetailViewController sample app and get the message "UIViewController may not respond to showRootPopoverButtonItem"
This worked in XCode 3.X, but I get the message with 4.2
The app itself functions 100%, the popover is recognized in every nib, as is the table on the left when in landscape mode. But I can't submit with this warning. What do I need to change??
RootViewController.h
#import <UIKit/UIKit.h>
/*
SubstitutableDetailViewController defines the protocol that detail view controllers must adopt. The protocol specifies methods to hide and show the bar button item controlling the popover.
*/
#protocol SubstitutableDetailViewController <NSObject>
- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem;
- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem;
#end
#interface RootViewController : UITableViewController <UISplitViewControllerDelegate> {
UISplitViewController *splitViewController;
UIPopoverController *popoverController;
UIBarButtonItem *rootPopoverButtonItem;
//UINavigationBar *navigationBar;
}
#property (nonatomic, assign) IBOutlet UISplitViewController *splitViewController;
#property (nonatomic, retain) UIPopoverController *popoverController;
#property (nonatomic, retain) UIBarButtonItem *rootPopoverButtonItem;
//#property (nonatomic, retain) IBOutlet UINavigationBar *navigationBar;
#end
RootViewController.m:
#import "RootViewController.h"
#import "WebViewController.h"
#import "Twitter.h"
//#import "SubstitutableDetailViewController.h"
#implementation RootViewController
#synthesize splitViewController, popoverController, rootPopoverButtonItem;//, navigationBar;
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
// Set the content size for the popover: there are just two rows in the table view, so set to rowHeight*2.
self.contentSizeForViewInPopover = CGSizeMake(310.0, self.tableView.rowHeight*2.0);
//self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:255/255 green:104/255 blue:1/255 alpha:1];
}
/*
-(void)customizeAppearance {
//create resizable images
UIImage *bluImage = [UIImage imageNamed:#"blu.jpg"];// resizableImageWithCapInsets:(0, 0, 0, 0)];
//set the bg for *all* UINavBars
[[UINavigationBar appearance] setBackgroundImage:bluImage forBarMetrics:UIBarMetricsDefault];
}
*/
-(void) viewDidUnload {
[super viewDidUnload];
self.splitViewController = nil;
self.rootPopoverButtonItem = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (void)splitViewController:(UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem
forPopoverController:(UIPopoverController*)pc {
// Keep references to the popover controller and the popover button, and tell the detail view controller to show the button.
barButtonItem.title = #"Index";
self.popoverController = pc;
self.rootPopoverButtonItem = barButtonItem;
UIViewController <SubstitutableDetailViewController> *detailViewController = [splitViewController.viewControllers objectAtIndex:1];
[detailViewController showRootPopoverButtonItem:rootPopoverButtonItem];
}
- (void)splitViewController:(UISplitViewController*)svc willShowViewController:(UIViewController *)aViewController
invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem {
// Nil out references to the popover controller and the popover button, and tell the detail view controller to hide the button.
UIViewController <SubstitutableDetailViewController> *detailViewController = [splitViewController.viewControllers objectAtIndex:1];
[detailViewController invalidateRootPopoverButtonItem:rootPopoverButtonItem];
self.popoverController = nil;
self.rootPopoverButtonItem = nil;
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section {
// Two sections, one for each detail view controller.
return 2;
}
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"RootViewControllerCellIdentifier";
// Dequeue or create a cell of the appropriate type.
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
//cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
// Set appropriate labels for the cells.
if (indexPath.row == 0) {
cell.textLabel.text = #"Twitter";
}
else if (indexPath.row == 1) {
cell.textLabel.text = #"Contact Us";
}
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.backgroundColor = [UIColor blackColor];
cell.contentView.backgroundColor = [UIColor blackColor];
cell.detailTextLabel.backgroundColor = [UIColor blackColor];
return cell;
}
#pragma mark -
#pragma mark Table view selection
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
/*
Create and configure a new detail view controller appropriate for the selection.
*/
NSUInteger row = indexPath.row;
UIViewController *detailViewController = nil;
if (row == 0) {
Twitter *newDetailViewController = [[Twitter alloc]
initWithNibName:#"Twitter"
bundle:nil];
detailViewController = newDetailViewController;
}
if (row == 1) {
WebViewController *newDetailViewController = [[WebViewController alloc]
initWithNibName:#"WebViewController"
bundle:nil];
newDetailViewController.detailURL=
[[NSURL alloc] initWithString:#"http://www.chipmunkmobile.com/contact.html"];
detailViewController = newDetailViewController;
}
// 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];
}
#pragma mark -
#pragma mark Managing the popover
/*
- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem {
// Add the popover button to the left navigation item.
[navigationBar.topItem setLeftBarButtonItem:barButtonItem animated:NO];
}
- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem {
// Remove the popover button.
[navigationBar.topItem setLeftBarButtonItem:nil animated:NO];
}
*/
#pragma mark -
#pragma mark Memory management
- (void)dealloc {
[popoverController release];
[rootPopoverButtonItem release];
[super dealloc];
}
#end
Here is an image of the exact line where I get the warning
The reason you getting this warning is because of this UIViewController *detailViewController UIViewController does not have a method called "showRootPopoverButtonItem". If you want to get rid of the warning just do this instead:
[(WebViewController*)detailViewController showRootPopoverButtonItem:self.rootPopoverButtonItem];
or
[(Twitter*)detailViewController showRootPopoverButtonItem:self.rootPopoverButtonItem];
You just need to let it know its not really just a viewController, its a subclassed viewController you created. So what ever class showRootPopoverButtonItem: is in you just need to type cast it.
If you want to leave your code exactly the same but get rid of the warning you can do this.
if (rootPopoverButtonItem != nil) {
[detailViewController performSelector:#selector(showRootPopoverButtonItem:) withObject:self.rootPopoverButtonItem];
}
If you want to be more careful you should use this.
if (rootPopoverButtonItem != nil && [detailViewController respondsToSelector:#selector(showRootPopoverButtonItem:)]) {
[detailViewController performSelector:#selector(showRootPopoverButtonItem:) withObject:self.rootPopoverButtonItem];
}
Update
After reading through your code you could just specify the delegate on the detailViewController like you did in the other functions.
UIViewController<SubstitutableDetailViewController> *detailViewController = nil;
if (row == 0) {
//...
(1)Specify the Type for the detailedViewController: [(TYPE *)OBJECTNAME...
(2) Then Specify method call [(TYPE *)OBJECTNAME METHODCALL];
(*) You get the warning because the compiler does not know what type of object you are using. If you subclass a UIViewController then you have to specify type when accessing methods.Make sure the method is in .h so that you can access it.