Having a bit of a problem, here's the breakdown:
My AppDelegate uses as it's rootViewController a view controller. This view controller's purpose is to swap a couple of other view controllers in and out, call it login and main screens. For the sake of simplicity I've removed any swapping code from the code that I will post and am having the rootViewController simply show it's first content view controller, say login.
The issue I'm having is that the content view controller seems to be pushed down a little bit inside the rootViewController. I've given the rootViewController a blue background and the content view controller an orange background. Here's my code:
AppDelegate.h
#import <UIKit/UIKit.h>
#class MainViewController;
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) MainViewController *main;
#end
AppDelegate.m
#import "AppDelegate.h"
#import "MainViewController.h"
#implementation AppDelegate
#synthesize main;
- (void)dealloc
{
[_window release];
[main release];
[super dealloc];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
MainViewController *mainVC = [[MainViewController alloc] init];
self.main = mainVC;
self.window.rootViewController = self.main;
[self.window makeKeyAndVisible];
return YES;
}
MainViewController.h
#import <UIKit/UIKit.h>
#class ContentViewController;
#interface MainViewController : UIViewController
#property (nonatomic, retain) ContentViewController *content;
#end
MainViewController.m
#import "MainViewController.h"
#import "ContentViewController.h"
#implementation MainViewController
#synthesize content;
- (id)init
{
self = [super init];
if (self ) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor blueColor];
ContentViewController *viewController = [[ContentViewController alloc] init];
self.content = viewController;
[self.view insertSubview:self.content.view atIndex:0];
}
- (void)dealloc {
[content release];
[super dealloc];
}
#end
ContentViewController.h
#import <UIKit/UIKit.h>
#interface LoginVC : UIViewController
#end
ContentViewController.m
#import "ContentViewController.h"
#implementation ContentViewController
- (id)init
{
self = [super init];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor orangeColor];
}
- (void)dealloc {
[super dealloc];
}
#end
The above codes gives me a status bar with a blue strip (approximately the height of the status bar) under it (which is the main view controller) followed by the orange content view controller taking up the rest of the screen. For some reason that main view controller seems to be pushing the content view controller down a little.
Strangely, if I create a view controller and use a XIB for drawing the view, it looks just fine and the content view it right up against the top of the main view.
If anybody could shed some light on this issue I'd very much appreciate it.
Cheers
I suppose that you shouldn't be doing
ContentViewController *viewController = [[ContentViewController alloc] init];
self.content = viewController;
[self.view insertSubview:self.content.view atIndex:0];
but rather:
ContentViewController *viewController = [[ContentViewController alloc] init];
self.content = viewController;
[self presentViewController:self.content animated:YES completion:nil];
Related
I am getting EXE_BAD_ACCESS exception when I hit "back" button on NavigationBar of my CreateViewController which is pushed on UINavigationController
When I enable following line in CreateViewController.m (full code at the bottom)
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.navigationController.navigationBar.hidden = NO;
//[self.textField becomeFirstResponder];
}
I start getting Thread1:EXE_BAD_ACCESS(code=1, address=...)
int main(int argc, char * argv[])
{
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
If I keep the above line of code disabled, then hitting back button takes me to MainViewController as expected.
I am a newbie to iOS. What I am doing wrong? Please see my code below.
Appdelegate.h
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#end
Appdelegate.m
import "AppDelegate.h"
import "MainViewController.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];
id controller = [[MainViewController alloc] initWithNibName:#"MainView" bundle:nil];
id navController = [[UINavigationController alloc] initWithRootViewController:controller];
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
return YES;
}
#end
MainViewController.h
#interface MainViewController : UIViewController
- (IBAction)create:(id)sender;
#end
MainViewController.m
import "MainViewController.h"
import "CreateViewController.h"
#implementation MainViewController
#pragma mark - View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (void)viewWillAppear:(BOOL)animated {
self.navigationController.navigationBar.hidden = YES;
}
- (IBAction)create:(id)sender {
id controller = [[CreateViewController alloc] initWithNibName:#"CreateView" bundle:nil];
[self.navigationController pushViewController:controller animated:YES];
}
#end
CreateView.h
#interface CreateViewController : UIViewController <UITextFieldDelegate>
#end
CreateView.m
- (void)viewDidLoad {
[super viewDidLoad];
[self.navigationController.navigationBar setTintColor:[UIColor purpleColor]];
self.textField=[[UITextField alloc] initWithFrame:CGRectMake(80, 10, 160, 30)];
[self.textField setBorderStyle:UITextBorderStyleRoundedRect];
self.textField.placeholder = #"Name";
[self.textField setBackgroundColor:[UIColor clearColor]];
self.textField.delegate = self;
[self.navigationController.navigationBar addSubview:self.textField];
self.navigationController.navigationBar.hidden = NO;
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.navigationController.navigationBar.hidden = NO;
//[self.textField becomeFirstResponder];
}
Go to breakpoint navigator and add exceptions breakpoint as shown below , 1st option :
Instead of adding self.textField as subview to navigation bar, set the textField as titleView of navigation item of the view controller.
[self.navigationItem setTitleView:self.textField];
This must help...
i have created a tabbed application and created another file, called LogInScreen,
I want to change the usual view which comes up at the application launch to this new LogInFile, but everything I tried didn't work.
This is the AppDelegate.h file:
#import <UIKit/UIKit.h>
#import "LogInScreen.h"
#interface LogInScreen : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) LogInScreen *logInView;
#end
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#end
At the first #implementation appears an error message: Duplicate interface definition for class 'LogInScreen', I guess because of the LogInScreen.h file. I don't know how to get it to work properly.
And this the start of the AppDelegate.m:
#import "AppDelegate.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
[self.logInView addSubview:_logInView.view];
[self.logInView makeKeyAndVisible];
[self.logInView setRootViewController:_logInView];
// Override point for customization after application launch.
return YES;
}
I found this code on this website, but it didn't work...
Here's the LogInScreen.h file:
#import <UIKit/UIKit.h>
#interface LogInScreen : UIViewController{
NSString *password;
IBOutlet UITextField *passwordField;
}
- (IBAction)enterPassword;
- (IBAction)savepassword:(id)sender;
- (IBAction)returnKey:(id)sender;
- (IBAction)switchView:(id)sender;
#end
and the LogInScreen.m:
#import "LogInScreen.h"
#import "FirstViewController.h"
/* #import "AppDelegate.h"
int main(int argc, char * argv[])
{
#autoreleasepool {
return UIApplicationMain()(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
*/
#interface LogInScreen ()
#end
#implementation LogInScreen
- (IBAction)enterPassword
{
NSString *passwordString = [NSString stringWithFormat:#"12345"];
if ([passwordField.text isEqualToString:passwordString]) {
/*[self switchView:nil]; */
}
else {
UIAlertView *incorrectPassword = [[UIAlertView alloc] initWithTitle:#"Falsches Passwort" message:#"Dieses Passwort ist falsch! Geben Sie bitte das korrekte Passwort ein!" delegate:self cancelButtonTitle:#"Zurück" otherButtonTitles:nil, nil];
[incorrectPassword show];
}
}
- (IBAction)savepassword:(id)sender {
password = [[NSString alloc] initWithFormat:passwordField.text];
[passwordField setText:password];
NSUserDefaults *stringDefault = [NSUserDefaults standardUserDefaults];
[stringDefault setObject:password forKey:#"stringKey"];
}
- (IBAction)returnKey:(id)sender {
[sender resignFirstResponder];
}
- (IBAction)switchView:(id)sender {
FirstViewController *main = [[FirstViewController alloc] initWithNibName:nil bundle:nil];
[self presentViewController:main animated:YES completion:NULL];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[passwordField setText:[[NSUserDefaults standardUserDefaults] objectForKey:#"stringKey"]];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Would be cool if someone could help me
Following my comment, you can use this code to show a modal login view before your main tabbed view:
// Main menu view controller
MainViewController *mainViewController = [[MainViewController alloc] initWithNibName:#"MainViewController" bundle:nil];
UINavigationController *mainNavigationController = [[UINavigationController alloc] initWithRootViewController:mainViewController];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.delegate = self;
self.tabBarController.viewControllers = [NSArray arrayWithObjects:mainNavigationController, nil];
self.window.rootViewController = self.tabBarController;
[self.window.rootViewController.view setOpaque:NO];
self.window.rootViewController.view.backgroundColor = [UIColor clearColor];
self.tabBarController.selectedIndex = 0;
[self.window setRootViewController:self.tabBarController];
[self.window makeKeyAndVisible];
// Login modal view controller
LoginViewController *loginController = [[LoginViewController alloc] initWithNibName:#"LoginViewController" bundle:nil];
[self.tabBarController presentViewController:loginController animated:NO completion:nil];
Place your login screen as intial view in MainStoryBoard .Drag a drop a uitabbarcontroller connect a segue from loginscreen to uitabbar and present modal that tabbar from a button in the login screen .
I've followed several guides on passing data between view controllers, but they seem to involve setting the secondViewController's property in any equivalent of a -(void)goToNextView method. I'm trying to figure out how to assign a value to a property in a 2nd view controller from the first while using a tab bar controller created in the app delegate.
Current setup:
AppDelegate.m
#synthesize window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
...
UITabBarController *tbc = [[UITabBarController alloc] init];
FirstViewController *vc1 = [[FirstViewController alloc] init];
SecondViewController *vc2 = [[SecondViewController alloc] init];
[tbc setViewControllers: [NSArray arrayWithObjects: vc1, vc2, nil]];
[[self window] setRootViewController:tbc];
[self.window makeKeyAndVisible];
return YES;
}
...
#end
FirstViewController.h
#import "SecondViewController.h"
#interface FirstViewController : UIViewController
{
SecondViewController *vc2;
IBOutlet UISlider *sizeSlider;
}
#property (nonatomic, retain) SecondViewController *vc2;
#property (strong, nonatomic) UISlider *mySlider;
-(IBAction) mySliderAction:(id)sender;
#end
FirstViewController.m
#import "FirstViewController.h"
#import "SecondViewController.h"
#implementation FirstViewController
#synthesize vc2, mySlider;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
UITabBarItem *tbi = [self tabBarItem];
[tbi setTitle:#"xib"];
}
return self;
}
...
- (IBAction) mySliderAction:(id)sender
{
NSString *str = [[NSString alloc] initWithFormat:#"%3.2f", mySlider.value];
if(self.vc2 == nil)
{
SecondViewController *viewTwo = [[SecondViewController alloc] initWithNibName:nil bundle:nil];
self.vc2 = viewTwo;
}
vc2.sliderValueString = str;
}
...
#end
SecondViewController.h
#import <UIKit/UIKit.h>
#import "myView.h"
#interface SecondViewController : UIViewController
{
NSString *sliderValueString;
}
#property (copy) NSString *sliderValueString;
#end
SecondViewController.m
#import "SecondViewController.h"
#implementation SecondViewController
#synthesize sliderValueString;
- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)bundle
{
self = [super initWithNibName:nil bundle:nil];
if (self) {
UITabBarItem *tbi = [self tabBarItem];
[tbi setTitle:#"View 2"];
}
return self;
}
-(void) loadView
{
CGRect frame = [[UIScreen mainScreen] bounds];
myView *view = [[myView alloc] initWithFrame:frame];
printf("Slider Value: %s", [sliderValueString UTF8String]);
[self setView: view];
}
...
#end
myView.h and .m are likely irrelevant to the question, but I've got the .h subclassing UIView, and the .m creating the view with -(id)initWithFrame:(CGRect)frame
I'm guessing that I'm assigning the 2nd VC's property in the wrong place (mySliderAction), given that the printf() in the 2nd VC is blank, so my question is: Where should the property be assigned, or what am I doing wrong that is preventing the 2nd VC from allowing it's sliderValueString to not be (or remain) assigned?
Thanks!
You are fine setting the property in mySliderAction, the trouble is that you are setting it on the wrong object.
In the App Delegate you create a viewController for tabControllers' item 2:
SecondViewController *vc2 = [[SecondViewController alloc] init];
In vc1's mySliderAction you also create an instance of vc2:
SecondViewController *viewTwo = [[SecondViewController alloc] initWithNibName:nil bundle:nil];
This is not the instance that you navigate to via the second tab on the tabController, but it is the one who's sliderValueString property you are setting.
Instead of making a new instance here, you need to refer to the already-existing instance:
SecondViewController *viewTwo = [self.tabBarController.viewControllers objectAtIndex:1]
Then you should be ok.
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;
}
i search for a way to have multiple detail view in iPad application and i find the sample code in apple developer site http://developer.apple.com/library/ios/#samplecode/MultipleDetailViews/Introduction/Intro.html , but now i want to have navigation in detail view which this sample does not cover, i add uinavigationcontroller to detail view as :
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
ReportsViewController_iPad *master = [[ReportsViewController_iPad alloc] initWithNibName:#"ReportsViewController_iPad" bundle:nil];
DetailViewController_iPad *detail = [[DetailViewController_iPad alloc] initWithNibName:#"DetailViewController_iPad" bundle:nil];
UINavigationController *masterNavController = [[[UINavigationController alloc] initWithRootViewController:master ] autorelease];
UINavigationController *detailNavController = [[[UINavigationController alloc] initWithRootViewController:detail ] autorelease];
splitViewController.viewControllers = [NSArray arrayWithObjects:masterNavController , detailNavController, nil];
[window addSubview:splitViewController.view];
[window makeKeyAndVisible];
return YES;
}
but when i run the sample i got error
[UINavigationController showRootPopoverButtonItem:]: unrecognized selector sent to instance...
showRootPopoverButtonItem is a method define in a protocol in RootViewController
#protocol SubstitutableDetailViewController
- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem;
- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem;
#end
---- ReportsViewController.h
#protocol SubstitutableDetailViewController
- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem;
- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem;
#end
#protocol DetailViewControllerManagerDelegate
-(void) didSelectRowAtIndexPathPopOver:(NSString *)ID;
#end
#interface ReportsViewController_iPad : ReportsViewController<UISplitViewControllerDelegate , DetailViewControllerManagerDelegate>
{
UISplitViewController *splitViewController;
UIPopoverController *popoverController;
UIBarButtonItem *rootPopoverButtonItem;
}
#property (nonatomic, assign) IBOutlet UISplitViewController *splitViewController;
#property (nonatomic, retain) UIPopoverController *popoverController;
#property (nonatomic, retain) UIBarButtonItem *rootPopoverButtonItem;
#property(nonatomic, retain) id<DetailViewControllerManagerDelegate> delegate;
-(void)didSelectRowAtIndexPath:(NSString*)ID;
#end
--DetailViewController.h
#import <UIKit/UIKit.h>
#import "ReportsViewController_iPad.h"
#interface DetailViewController_iPad : UIViewController<SubstitutableDetailViewController>
{
UIToolbar *toolbar;
}
#property (nonatomic, retain) IBOutlet UIToolbar *toolbar;
#end
--DetailViewController.m
#import "DetailViewController_iPad.h"
#implementation DetailViewController_iPad
#synthesize toolbar;
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
#pragma mark -
#pragma mark Managing the popover
- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem {
// Add the popover button to the toolbar.
NSMutableArray *itemsArray = [toolbar.items mutableCopy];
[itemsArray insertObject:barButtonItem atIndex:0];
[toolbar setItems:itemsArray animated:NO];
[itemsArray release];
}
- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem {
// Remove the popover button from the toolbar.
NSMutableArray *itemsArray = [toolbar.items mutableCopy];
[itemsArray removeObject:barButtonItem];
[toolbar setItems:itemsArray animated:NO];
[itemsArray release];
}
- (void)dealloc {
[toolbar release];
[super dealloc];
}
#end
So Thanks in advance.
Where definition of method showRootPopoverButtonItem is present, seems like this is not defined. You need to define it.
If you want to avoid crash then you can use -
if ([aViewController respondsToSelector:#selector(showRootPopoverButtonItem:)]) {
[aViewController performSelector:#selector(showRootPopoverButtonItem:) withObject:self.rootPopoverButtonItem];
}
EDIT -
I have checked this and found what you are doing wrong , for e.g. code in willHideViewController-
UIViewController <SubstitutableDetailViewController> *detailViewController = [splitViewController.viewControllers objectAtIndex:1];
this is expecting a view controller, while you are passing navigation controller which in turn has view controller(similar at some other position), so you need to alter these codes as well if you want to pass navigation controller from app delegate.