I have using split view in my application.
When i run my application in iOS 6 simulator it rotates as per orientation changes and works well but when i run same application in iOS 5 or iOS 5.1 simulator and i change orientation of simulator but split view not changes as per orientation change.
I also add code
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown || interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
-(BOOL)shouldAutorotate
{
return YES;
}
And I add split view using following code
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
above method in both Master View and Detail View.
And I added split view using following code
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
// obj_PageControlViewController = [[PageControlViewController alloc]initWithNibName:#"PageControlViewController-iPad" bundle:nil];
MasterViewController *masterViewController = [[MasterViewController alloc] initWithNibName:#"MasterViewController_iPad" bundle:nil];
UINavigationController *masterNavigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController_iPad" bundle:nil];
UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
masterViewController.detailViewController = detailViewController;
self.splitViewController = [[UISplitViewController alloc] init];
self.splitViewController.delegate = detailViewController;
self.splitViewController.viewControllers = #[masterNavigationController, detailNavigationController];
TabBarAppDelegate *appDelegate = (TabBarAppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.window setRootViewController:self.splitViewController];
}
but it's not work. Any one can help me?
You say you added shouldAutorotateToInterfaceOrientation: but you didn't say where you added it. To get autorotation of a UISplitViewController in iOS 5.1 or earlier, you must supply shouldAutorotateToInterfaceOrientation: in the view controllers of both child view controllers of the split view controller (both the master and the detail view controllers).
That will work, assuming that the split view controller is the top-level (root) view controller of your application, as set up by the Master-Detail template.
Oh, and save yourself some trouble: in shouldAutorotateToInterfaceOrientation:, just return YES. On iPad, you always want to autorotate.
In iOS5 and below you should use
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
The one you posted above (shouldAutorotate) is for iOS6+
Related
I would like to create an application like this:
On iphone (both portrait and landscape) and ipad portrait, I have a table view screen, tap on item row will navigate to another detail screen look like other basic application.
But when I rotate screen to go to landscape on ipad, the screen now has two section views
Here is what I did:
Write a method isInLandscapeTablet to detect ipad landscape
Use UINavigationController as a root controller to control all other views
In portrait screen, push a viewcontroller contains tableview to root controller
In landscape tablet screen, attach tableview controller and detail controller to UISplitViewController, then push it into root controller
But the problem is I can't push UISplitViewController to root controller, as it requires to be a root controller.
I wonder how I can handle this problem
And is my approach correct? Is there any other way?
Update: I change the root view controller like this
// this snippet is in UINavigationController (I use as root viewcontroller)
if([self isInTabletLandscape]){
self.splitViewController.viewControllers = [NSArray arrayWithObjects:[[CategoryViewController alloc] initWithNibName:#"CategoryViewController" bundle:nil], self.propertyLandViewController, nil];
[[UIApplication sharedApplication].keyWindow setRootViewController:self.splitViewController];
}else{
// it doesn't work
[[UIApplication sharedApplication].keyWindow setRootViewController:self];
}
}
After knowing the device whether it is iPad or iPhone. You Can try to remove the RootViewController.
appDelegate.window.rootViewController = nil;
Then you set the root view controller with a new SplitViewContloller
id objClass =[[SplitViewController alloc]initWithNibName:#"SplitViewController" bundle:nil];
masterVC.delegate = detailVC;
detailVC.delegate = objClass;
[objClass setViewControllers:#[masterNavigate,detailNavigate]];
[appDelegate.window setRootViewController:objClass];
My suggestion is not to use Split View Controller at all. Create a custom View Controller, which will embed your table view controller and the 2nd controller. Also, you can implement the interface-rotation logic in the custom controller you create.
If you are developing on iOS 8 you should use Size Classes, so you can totally change the layout depending on iPhone/iPad portrait and iPad Landscape. Unfortunately on iOS 7, size classes only differentiate iPhone and iPad.
In both case the right part (2), can be easily handle with a containerView.
https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/ViewControllerCatalog/Chapters/SplitViewControllers.html
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
MyFirstViewController* firstVC = [[MyFirstViewController alloc] init];
MySecondViewController* secondVC = [[MySecondViewController alloc] init];
if ( ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait) ){
UISplitViewController* splitVC = [[UISplitViewController alloc] init];
splitVC.viewControllers = [NSArray arrayWithObjects:firstVC, secondVC, nil];
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
window.rootViewController = splitVC;
[window makeKeyAndVisible];
}
else
{
// Display tableview
}
return YES;
}
I assume this may help you..
I'm having trouble calling a newly created view controller within the storyboard. I have created an app using the default master-detail template. The only simple thing I'd like to do is call a new View Controller window when a specific check is valid/invalid (depending on requirement) (I refuse to use the term "Login" :-) ).
What is the best location to do this? In here (appDelegate)?
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
splitViewController.delegate = (id)navigationController.topViewController;
UINavigationController *masterNavigationController = splitViewController.viewControllers[0];
MasterViewController *controller = (MasterViewController *)masterNavigationController.topViewController;
controller.managedObjectContext = self.managedObjectContext;
} else {
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
MasterViewController *controller = (MasterViewController *)navigationController.topViewController;
controller.managedObjectContext = self.managedObjectContext;
}
//Should I call the new view controller object from my storyboard at this location? (i.e. myView)
return YES;
}
I'm even considering starting all over without using the template of Xcode.
Do you need to use different controllers depending on check result?
If yes than there are few suggestions. You can cover your view with some activity view which covers all screen, wait for checking and than remove activity view.
Another thing you can try is making another view controller in storyboard and move starting arrow to it. You can try to login and after it perform correct segue.
And at least i can suggest to create root view controller programmatically.
something like this.
- (void)applicationDidFinishLaunching:(UIApplication *)application {
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
levelViewController = [[LevelViewController alloc] init];
window.rootViewController = levelViewController;
[window makeKeyAndVisible];
}
I've looked at a few examples but I haven't been able to get things to work properly yet. I am in a large code base that is a universal app. I am bringing in a .xib like so:
TestView *newView =
[[TestView alloc] init];
[self presentViewController:newView animated:YES completion:nil];
That loads the .xib just fine on the iPhone side of things, but in the iPad sim the .xib covers the whole screen. How can I make it to only cover the details view? I understand that in the appdelegate it makes two view controllers (i.e. the splitviewcontroller) but I have no option to do something like
[detailViewController presentViewController:newView animated:YES completion:nil];
You have to create an instance of a UISplitViewController in the AppDelegate. The UISplitViewController is only availabe on the iPad, so you have to enclose this in an if-statement
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
UIViewController *master = [self buildMaster];
UIViewController *detail = [self buildDetail];
UISplitViewController *splitViewController = [[UISplitViewController alloc] init];
splitViewController.viewControllers = #[master, detail];
[self.window setRootViewController:splitViewController];
}
I know there is a lot of discussion on this topic on stack overflow, but none of the questions have an answer that works for me.
I have a SplitViewController that loads as the root view controller, and both of the tableviews inside the SVC have ShouldAutoRotate set to return YES.
The SVC won't rotate with the iPad correctly, even though the clock / status bar do.
Update
In my AppDelegate, I've noticed that the rootViewController isn't actually set until after I set it - shouldn't the rootViewController always be set?
This code:
MyAppAppDelegate *appDelegate = (MyAppAppDelegate *)[[UIApplication sharedApplication] delegate];
NSLog(#"RootViewController pre set: %#", appDelegate.window.rootViewController);
[appDelegate.window setRootViewController:splitViewController];
NSLog(#"RootViewController post set: %#", appDelegate.window.rootViewController);
Logs as:
RootViewController pre set: (null)
RootViewController post set: <UISplitViewController: 0x88ad2d0>
Does this mean that I am mistaken in thinking the SVC is the root view controller?
Also, in IB - the window has nothing hooked up to the rootViewController outlet - is this a problem?
Here's where the SVC is programmatically made:
-(IBAction)makeStory:(id)sender{
MakeSentenceTableViewController *detailViewController = [[MakeSentenceTableViewController alloc] initWithNibName:#"MakeSentenceTableViewController" bundle:nil];
UISplitViewController *splitViewController = [[[UISplitViewController alloc] init] autorelease];
UINavigationController *rootNav = [[[UINavigationController alloc] initWithRootViewController:makeStoryTableViewController]autorelease];
UINavigationController *detailNav = [[[UINavigationController alloc] initWithRootViewController:detailViewController] autorelease];
splitViewController.viewControllers = [NSArray arrayWithObjects:rootNav, detailNav, nil];
splitViewController.delegate = makeStoryTableViewController;
MyAppAppDelegate *appDelegate = (MyAppAppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.window setRootViewController:splitViewController];
}
Here is the ShouldAutoRotate section in both tableviews (they're identical in both):
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
NSLog(#"story idiom for rotate is iPad");
return YES;
}
Please help me fix this so that the SplitViewController loads correctly - or help me out with some techniques to debug (e.g. how could I check for sure that the SVC is in the rootViewController, are there other methods to debugging rotation hassles?).
Ah. So often part of the process in asking a question leads you to answer it to yourself.
I had to hook up the rootViewController outlet in IB for MainWindow~ipad.xib to the viewController in the AppDelegate, then everything started working.
So I hadn't correctly set the UISplitViewController as the rootViewController.
i have the following problem.
I'm developing an app with a splitViewController as the root controller. In the appDelegate i have this code in method didFinishLaunchingWithOptions:
[self.window addSubview:splitViewController.view];
[self.window makeKeyAndVisible];
self.sendData = [[[SendData alloc] init] autorelease];
showEventsViewController.sendData = self.sendData;
LoginView *lvc = [[LoginView alloc] initWithNibName:#"LoginView" bundle:nil];
lvc.delegate = self;
[splitViewController presentModalViewController:lvc animated:NO];
[lvc release];
return YES;
When the login is complete, i dismiss the loginView and i show the splitViwController.
Besides, my application needs to run only in landscape mode, so i have configured the plist in order to avoid only landscape mode and set this code in each view controller:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Overriden to allow any orientation.
if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft)
return YES;
if (interfaceOrientation == UIInterfaceOrientationLandscapeRight)
return YES;
return NO;
}
But when i run my app in portrait mode (the login view is shown right in landscape) and icomplete the login, the splitview is shown in landscape mode but the detailViewController is whole black (the master view is in landscape mode)
What is happening?
Thanks