iOS - How to present different scenes from UITableViewCell - ios

I have a UIViewController with a TableView. The TableView is populated with an image and a text for each cell. Now I need to present others Scenes when the user taps a cell. For example:
- tap on first row --> present ViewController1 - tap on second row --> present ViewController2
ViewController1 and ViewController2 are scenes in my Storyboard.
I've tried various solutions, but none of these works. Moreover it seems that the method didSelectRowAtIndexPath: is not called when I tap a cell (for example I tried to show up an alert).
Here the code of my ViewController:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
{
NSArray *recipes;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
recipes = [NSArray arrayWithObjects:#"News", #"Calendar",#"Take a photo",#"Draw",#"Mail us",#"Follow us on Facebook", nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [recipes count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [recipes objectAtIndex:indexPath.row];
if ([cell.textLabel.text isEqualToString:recipes[0]]) {
cell.imageView.image = [UIImage imageNamed:#"newsicon"];
}
else if ([cell.textLabel.text isEqualToString:recipes[1]]) {
cell.imageView.image = [UIImage imageNamed:#"mensaicon"];
}
else if ([cell.textLabel.text isEqualToString:recipes[2]]) {
cell.imageView.image = [UIImage imageNamed:#"fotoicon"];
}
else if ([cell.textLabel.text isEqualToString:recipes[3]]) {
cell.imageView.image = [UIImage imageNamed:#"drawicon"];
}
else if ([cell.textLabel.text isEqualToString:recipes[4]]) {
cell.imageView.image = [UIImage imageNamed:#"mailicon"];
}
else if ([cell.textLabel.text isEqualToString:recipes[5]]) {
cell.imageView.image = [UIImage imageNamed:#"fbicon"];
}
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// here we get the cell from the selected row.
UITableViewCell *selectedCell=[tableView cellForRowAtIndexPath:indexPath];
if ([selectedCell.textLabel.text isEqualToString:recipes[0]]) {
UIAlertView *messageAlert = [[UIAlertView alloc]
initWithTitle:#"Row Selected" message:#"You've selected a row" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
// Display Alert Message
[messageAlert show];
NSString *storyboardName = #"Main";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"news"];
[self presentViewController:vc animated:YES completion:nil];
}
// use the image in the next window using view controller instance of that view.
}
#end
I'm new to iOS developing, so I don't know if my code is right or if there are other solutions more elegant of these. Anyway, let's focus on the problem, can anyone help me?

If your view is only a table view I'd suggest using a UITableViewController instead of a UIViewController. If you have a UITableView in an existing UIViewController you need to set up the delegate and data source methods yourself.
You can do this in the storyboard. Click on your tableView and then select the connections inspector. Then click the circle next to dataSource and drag it to your view controller. Do the same for delegate. This is probably why your table view methods aren't being called.
If it's a static table, you can create independent segues from each cell in the storyboard.

Moreover it seems that the method didSelectRowAtIndexPath: is not called when I tap a cell (for example I tried to show up an alert).
Your based class is UIViewController, therefore, your UITableViewDelegate and UITableViewDataSource won't get set automatically. You need to do it yourself. For example, you can set them in the init function:
- (instancetype)init {
self = [super init];
if( self ) {
self.delegate = self;
self.datasource = self;
}
return self;
}
An alternative is to use UITableViewController as your base call, then you don't need to worry about setting the delegates.

according to your code alert will only be shown when you click on 1st cell only..
but according to your needs let me write a code for that will help you..
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// here we get the cell from the selected row.
NSString *selectedcelltext=[recipes objectAtIndex:indexPath.row];
UIAlertView *messageAlert = [[UIAlertView alloc]
initWithTitle:#"Row Selected" message:[NSString stringWithFormat:#"You've selected a %# row ",selectedcelltext] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
// Display Alert Message
[messageAlert show];
if ([selectedcelltext isEqualToString:recipes[0]]) {
NSString *storyboardName = #"Main";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"news"];
[self presentViewController:vc animated:YES completion:nil];
}
else if ([selectedcelltext isEqualToString:recipes[1]]) {
NSString *storyboardName = #"Main";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"calendar"];
[self presentViewController:vc animated:YES completion:nil];
}
// use the image in the next window using view controller instance of that view.
}

Related

iOS Animation Issues

Hopefully someone can help me out. Recently I have been having issues with the animations inside my view. I have been unable to find a solution to it but until now it has been fine as nothing major was going on inside the view, but now I have an alert view showing inside the view after I click a table cell. The alert view comes from the top right hand corner of the screen and goes down the screen and gets bigger with the black background. I just want it to appear without coming down from the right hand top corner. I have always used the same method of showing alert views and never had animation issues before in my views. I will attach a link to the gif below. I will also add the code for the view.
GIF:
https://imgflip.com/gif/x61vg
Track1.h
//
// Track1.h
// uDropOff 3
//
// Created by Curtis Boylan on 06/01/2016.
// Copyright © 2016 Curtis Boylan. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "TableViewCell.h"
#interface Track1 : UIViewController <UITableViewDelegate,UITableViewDataSource>
- (IBAction)back;
#property (weak, nonatomic) IBOutlet UITextField *trackingnumber;
- (IBAction)track;
#property (weak, nonatomic) IBOutlet UITableView *tableViewObject;
#end
Track1.m
//
// Track1.m
// uDropOff 3
//
// Created by Curtis Boylan on 06/01/2016.
// Copyright © 2016 Curtis Boylan. All rights reserved.
//
#import "Track1.h"
#import "TableViewCell.h"
#interface Track1 ()
#end
#implementation Track1
{
NSMutableArray *tableAray;
}
- (void)viewDidLoad {
[super viewDidLoad];
tableAray = [[NSMutableArray alloc] initWithObjects:#"test",#"test2", nil];
// [self webstuff1];
// Do any additional setup after loading the view.
// UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
// [refreshControl addTarget:self action:#selector(handleRefresh:) forControlEvents:UIControlEventValueChanged];
// [self.table addSubview:refreshControl];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
- (IBAction)back {
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#"main"];
[self presentViewController:vc animated:YES completion:NULL];
}
- (IBAction)track {
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// saving an NSString
[prefs setObject:self.trackingnumber.text forKey:#"uDropOffTracking"];
Track1 *track2 = [self.storyboard instantiateViewControllerWithIdentifier:#"track2"];
[self presentViewController:track2 animated:NO completion:nil];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [tableAray count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 70;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"TableViewCell";
TableViewCell *cell = (TableViewCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nibArray = [[NSBundle mainBundle] loadNibNamed:#"TableViewCell" owner:self options:nil];
cell = [nibArray objectAtIndex:0];
}
cell.tracking.text = [tableAray objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIAlertView *selectedAlert = [[UIAlertView alloc]
initWithTitle:[NSString stringWithFormat:#"%# Selected", [tableAray objectAtIndex:indexPath.row]] message:[NSString stringWithFormat:#"It takes 20 mins to prepare!"] delegate:nil cancelButtonTitle:#"Got It" otherButtonTitles:nil];
[selectedAlert show];
}
#end
Thanks!
Do you use
[UIView beginAnimations: context:];
somewhere in your code?
Make sure call
[UIView commitAnimations];
right after setting animation option.
I have found the solution, along with Vu's answer I done the following in my other view which was displaying track1.
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#"track1"];
vc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:vc animated:YES completion:NULL];}
Changing it to the following and along with the solution Vu had fixed my issues:
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#"track1"];
[self presentViewController:vc animated:NO completion:NULL];}

iOS - How to prevent all my titles from changing

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.

iPhone open multiple view controllers on table view item click

Is it possible to open different view controllers depending on witch table view cell user clicks? I tried to do that with:
[self presentViewController:obj animated:YES completion:nil];
but when next view is presented, there is no navigation bar and I can't go back to table view.
EDIT:
Here is MasterViewController class that I am using
#import "MasterViewController.h"
#interface MasterViewController () {
NSArray *viewArray;
}
#end
#implementation MasterViewController
#synthesize items,itemImges;
- (void)awakeFromNib
{
if ([[[UIDevice currentDevice] systemVersion] compare:#"7" options:NSNumericSearch] != NSOrderedAscending) {
self.preferredContentSize = CGSizeMake(320.0, 480.0);
}
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
self.clearsSelectionOnViewWillAppear = NO;
}
self.title = NSLocalizedString(#"MasterTitle",#"Options:");
[super awakeFromNib];
}
- (void)viewDidLoad
{
[super viewDidLoad];
items = [NSArray arrayWithObjects:#"Media Explorer",#"Live TV",#"Settings",nil];
itemImges = [NSArray arrayWithObjects:
[UIImage imageNamed:#"listicon_guide.png"],
[UIImage imageNamed:#"listicon_livetv.png"],
[UIImage imageNamed:#"listicon_settings.png"],
nil];
// Do any additional setup after loading the view, typically from a nib.
self.detailViewController = (DetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];
MediaExpDetailViewController *DVCA = [self.storyboard instantiateViewControllerWithIdentifier:#"MediaExpDetailViewController"];
LiveTVDetailViewController *DVCB = [self.storyboard instantiateViewControllerWithIdentifier:#"LiveTVDetailViewController"];
SettingsDetailViewController *DVCC = [self.storyboard instantiateViewControllerWithIdentifier:#"SettingsDetailViewController"];
//Create Array of views
viewArray = [NSArray arrayWithObjects:DVCA, DVCB, DVCC, nil];
}
#pragma mark - Table View
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return items.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
NSString *object = items[indexPath.row];
UIImage *image = itemImges[indexPath.row];
cell.textLabel.text = [object description];
cell.imageView.image = image;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//for iPad
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
//something goes here
}
else { //for iPhone
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
MediaExpDetailViewController *objSynergy = (MediaExpDetailViewController *)[mainStoryboard instantiateViewControllerWithIdentifier:#"MediaExpDetailViewController"];
[self.navigationController pushViewController:objSynergy animated:YES];
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
}
#end
First set Storyboard IDs for your Next View controllers in Interface Builder and then.
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Check Row and Select Next View controller
if (indexPath.row == 1)
{
// Push Selected View
UIViewController *view1 = [self.storyboard instantiateViewControllerWithIdentifier:#"StoryboardID"];
[self.navigationController pushViewController:view1 animated:YES];
}
}
That's because
[self presentViewController:obj animated:YES completion:nil];
Presents the new view controller modally (over top of the existing visible controller). If you want to push to a new view controller using your navigation controller, you'll want to use this. Of course you'll want to make sure that the view controller you're pushing from is embedded within a UINavigationController.
[self.navigationController pushViewController:obj animated:YES];
And to answer your first question, yes it absolutely is possible. Just add some condition logic to your didSelectRowAtIndexPath: UITableViewDelegate method.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (someCondition) {
[self.navigationController pushViewController:obj animated:YES];
}else{
[self.navigationController pushViewController:otherObj animated:YES];
}
}
Modally presented view controllers don't have navigation bars by default. You have to embed them in a UINavigationController, in order to have one. You should also implement how to dismiss the presented view controller by yourself, calling dismissViewControllerAnimated at the appropriate times.
However, I'd recommend to push your view controllers (with pushViewControllerAnimated), instead of presenting them modally, if you don't specifically need the modal functionality.

Apply Condition in DidselectRowAtIndexPath

I have a UITableView which has different types of files and folders in it, Right i have set a method that passes to another view controller once clicked on a row. What i need is that once a row is clicked on it checks what kind of a file is in the row and then connects to different uiviewcontrollers on the basis of that.
My UiTableView has two items in each cell
A Cell Label & Cell Detail Text Label
The DetailTextLabel holds the Subject type
i.e. Folder (For Folders) & File (For Files like jpeg. , png., etc.)
I want to use the if condition in the didselectrowatindexpath to distinguish between file and folder
You can do that by checking value of cell.detailTextLabel.text like following:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell * cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *str = cell.detailTextLabel.text;
if ([str isEqualToString:#"Folder"])
{
// Open Folder Detail View. For Example:
FolderViewController* objVC = [[FolderViewController alloc] initWithNibName:#"FolderViewController" bundle:nil];
[self.navigationController pushViewController:objVC animated:YES];
}
else if ([str isEqualToString:#"File"])
{
// Open File Detail View. For Example:
FileViewController* objVC = [[FileViewController alloc] initWithNibName:#"FileViewController" bundle:nil];
[self.navigationController pushViewController:objVC animated:YES];
}
}
in .h file
#import "FolderViewController.h"
#import "FileViewController.h"
#interface mainViewController : UIViewController {
FolderViewController *folderViewObj;
FileViewController *fileViewObj;
}
in .m file
- (void)viewDidLoad {
[super viewDidLoad];
folderViewObj = [[FolderViewController alloc] initWithNibName:#"FolderViewController" bundle:nil];
fileViewObj = [[FileViewController alloc] initWithNibName:#"FileViewController" bundle:nil];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell * cell = [tblObj cellForRowAtIndexPath:indexPath];
NSString *lblText = cell.DetailTextLabel.text;
if ([lblText isEqualToString:#"Folder"]) {
[self.navigationController pushViewController:folderViewObj animated:YES];
}
else if ([lblText isEqualToString:#"File"])
{
[self.navigationController pushViewController:fileViewObj animated:YES];
}
}
-(void) dealloc {
[folderViewObj release];
[fileViewObj release];
[super dealloc];
}
using this way, object of FolderViewController and FileViewController is created only once not all time when user can select the row of uitableview.

UIViewController may not respond to showRootPopoverButtonItem

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.

Resources