Rotate only one view in tab bar - ios7

I have a tab bar with four items. i need to rotate only one item, but i don't understand how to do.I tried this, but doesn't work.
- (BOOL)shouldAutorotate
{
return NO;
}
I'm working in ios 7 and storyboard.
Thanks

Unfortunately you can't do that. Whatever the allowed rotation settings are for the tab bar controller (through its delegate method tabBarControllerPreferredInterfaceOrientationForPresentation:), those are the allowed rotation settings for all of its items. The only way to force rotation in iOS 7 is to put up a presented (modal) view with presentViewController: (modal segue).

I found the solution in this example
http://www.raywenderlich.com/forums/download/file.php?id=1464&sid=42c0876f615fa632a49be7b89d203f6e

Related

Need a way to force a UIInterfaceOrientation rotation without iOS device rotating

I need to know if there is a way to tell a iOS7 device to set a views orientation without the device being rotated. Some way in code to trigger the device to calling the code that tells it which way to display the view.
If the device is in landscape and remains held in landscape orientation while a certain change happens I want to force a change to show the view in portrait orientation, at which point the user would need to turn the device to look at it properly. I'll explain why below
Looking at my app might make my description clearer - it is free to download
I have a number of view controllers (embedded in navigationControllers) and only one of them needs to be rotated into landscape and then only under certain conditions.
Solutions here on StackOverflow seem to be to make a category on UINavigationController giving it shouldAutorotate and supportedInterfaceOrientations methods and then use those methods in the individual viewControllers to block or allow rotations.
This has worked for me .... however
On the one view controller I wish to rotate , I don't want it to rotate all the time.
This view controller is the diveSiteDetailsController, (if you have downloaded the app you need to select dive sites on the first page then click the '+' to see it). It has a UISegmentedController and 4 subviews (3 tableviews and 1 other UIView). The current version on the App Store works fine now i've solved this - but looking at it may help you understand my issue better).
On diveSiteDetailViewController the UISegmentedController is used to switch between the 4 subviews.
All the subviews are used to enter data about the same dive site but as there is a lot of potential data, I have broken it into logical chucks each of which is a subview - location, data (depths,currents, visibility), type of environment and notes.
The .hidden property of each subview is used to make them appear and disappear.
I only want the second subview to rotate (the data view - it has some sliders on it that are easier to work with if in landscape).
restricting this rotation is easy - iI achieved it like this
- (NSUInteger)supportedInterfaceOrientations{
if (self.dsDataRangeSlidingTV.hidden) {
return UIInterfaceOrientationMaskPortrait;
}
return UIInterfaceOrientationMaskAllButUpsideDown;
}
Now the view will only rotate to landscape when the data table view is displayed.
However, once in landscape, if I chose a different subview with the UISegmentedController then they are, obviously, shown in landscape also as the iOS device hasn't done a rotation. This is the situation I am trying to avoid.
Rotating the iOS device will return those views to portrait as expected but i need to trigger the device to to reevaluate its display when I use the UISegmentedController to switch from the data subview to another subview and its that triggering that I don't know how to do.
any suggestions greatly received.
Heres a workaround that is working for me
I've added the following few lines to the end of my method that responds to the UISegmentedControl being tapped.
UIViewController *aDummyController = [[UIViewController alloc]init];
[self presentViewController:aDummyController animated:NO completion:nil];
[self dismissViewControllerAnimated:NO completion:nil];
adding a new viewController and popping it off triggers the rotation . This is a kludgey way of achieving what I wanted.
I found the solution in this post
Is there a documented way to set the iPhone orientation?
all credit to Josh who although not the accepted answer is the one that 99 people currently have up voted.
I still have a bug in that, if I were holding the device in landscape (although the display is portrait view) whilst on the screen that segues into the diveSiteDetailsController then the initial view the diveSiteDetailsController display will be in landscape.
To get around this I created a Bool property called notThisTime on the diveSiteDetailsController and set it to true in the prepareFor Segue on the viewController that called it.
i then did changed supportedInterfaceOrientation to
- (NSUInteger)supportedInterfaceOrientations
{// DLog(#"Running %# '%#'", self.class, NSStringFromSelector(_cmd));
if (self.notThisTime){
return UIInterfaceOrientationMaskPortrait;
}
if (!self.dsDataRangeSlidingTV.hidden) {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
then at the end of the ViewDidLoad method I added
self.notThisTime = NO;
I would still love to hear from anyone with a suggestion how better to handle this. pushing and popping a dummy view to get the iPhone to do an orientation check seems like a work around for something that should just be available as a standard method call.
One final Note - the iOS simulator does not like this - you need to check on the device - it sometimes tries to draw the iPhone container in landscape while the screen is drawn vertically - however it does work fine on the iPhone

How to set the UITableView pulling area?

As you can see, this is a UITableView, when the user pull down, there is some white area appear, is this possible to limit the size of this area? Thanks.
If your iOS6 project has no problem and the iOS7 project has this problem , I think you are find this property : self.automaticallyAdjustsScrollViewInsets = NO;
This property is added by iOS7.
automaticallyAdjustsScrollViewInsets Specifies whether or not the view
controller should automatically adjust its scroll view insets.
#property(nonatomic, assign) BOOL automaticallyAdjustsScrollViewInsets
Discussion Default value is YES, which allows the view controller to
adjust its scroll view insets in response to the screen areas consumed
by the status bar, navigation bar, and toolbar or tab bar. Set to NO
if you want to manage scroll view inset adjustments yourself, such as
when there is more than one scroll view in the view hierarchy.
Availability Available in iOS 7.0 and later.
I think you can add this : self.automaticallyAdjustsScrollViewInsets = NO; in your viewController class to solve this problem
Your helper is cocoacontrols select->download -> research - > clone git -> pull your bug fix :D

Minimum steps to get autorotate to work

I've trying to implement autorotate but my app is not listening to me!
The app has a tab bar controller which supervises 3 view controllers. The tab bar is created programatically in the app delegate. Each of the view controllers has this standard simple method:
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
The app delegate looks like this:
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:gameVC, settingsVC, helpVC, nil];
self.window.rootViewController = self.tabBarController;
In addition, in the target summary area I have all 4 orientations for both the iPad and iPhone activated.
In the simulator, no rotation occurs with either device. I seem to be missing something. Perhaps one more setting is needed? Something out of order? There is nothing else in the project related to rotating views.
The only thing that you seemed to not have said in your response that I can think of is changing the device orientations under your info.plist. I know from personal experience that if you click on the supported device orientations in the target summary area, it might not actually change it in the Info property list. Check and make sure that all four are selected in the property list by doing the following:
Go to your Info.plist
Look under Supported interface orientations and Supported interface orientations (iPad)
Make sure that it has 4 strings under both: Portrait (bottom home button), Portrait (top home button), Landscape (left home button), Landscape (right home button)
User a ViewController for super purpose, and then inheritance it in the each of view controllers. In the super ViewController add this
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
return YES;
}
So, you just need to do once to make them autorotate
from http://developer.apple.com/library/ios/#DOCUMENTATION/WindowsViews/Conceptual/ViewControllerCatalog/Chapters/TabBarControllers.html#//apple_ref/doc/uid/TP40011313-CH3-SW26
Tab bar controllers support a portrait orientation by default and do
not rotate to a landscape orientation unless all of the contained view
controllers support such an orientation. When a device orientation
change occurs, the tab bar controller queries its array of view
controllers. If any one of them does not support the orientation, the
tab bar controller does not change its orientation.
#Zack #AlexanderZats This was subtle. I was reading this SO answer which brought me here This 2nd link is a great discussion of different possible reasons an app may not rotate. The last point caught my attention. Sure enough, I was overriding initWithNibName and not calling super on it. I think this ultimately meant that the the VCs were not in the responder chain. A huge thanks to all who gave me ideas and suggestions!

Resize master and detail view controllers in a split view controller?

I'm working in Xcode 4.2 and am developing an app where I want the menu screen to use a Split View. Really, all I need the Split View Controller for is to split some of the menu options into a left pane and right pane. I want to be able to set custom sizes for the master and detail view controllers, but nothing seems to be working for me. I've tried updating the frame sizes for each view controller with code like:
[self.view setFrame:CGRectMake(0, 0, 768, 502)];
in the viewDidLoad functions, but that doesn't seem to affect anything.
Is there a way to set custom sizes for the master and detail view controllers of a split view controller without instantiating the view controllers in say the AppDelegate.m file? I want to be able to edit each of the view controllers in the storyboard as they are menu screens with a lot of buttons and such.
Edit:
In iOS 8+, the relative widths can be changed by specifying the minimum/maximumPrimaryColumnWidth properties or the preferredPrimaryColumnFraction.
The below answer is still true for iOS < 8:
You can't change the sizes for a split view controller.
See here: http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/Introduction/Introduction.html
"The UISplitViewController class is a container view controller that manages two panes of information. The first pane has a fixed width of 320 points and a height that matches the visible window height. The second pane fills the remaining space."
Use MGSplitViewController. It offers similar API to UIViewController, but offering additional features, such as split position, which is what you need.
- (CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMinimumPosition ofSubviewAt:(NSInteger)dividerIndex;
{
return proposedMinimumPosition + 238;
}
- (CGFloat)splitView:(NSSplitView *)splitView constrainMaxCoordinate:(CGFloat)proposedMaximumPosition ofSubviewAt:(NSInteger)dividerIndex;
{
return proposedMaximumPosition - 200;
}
before the above delegate method add [splitView addDelegate:self];

Can I use a UINavigationController as the detail view of a UISplitViewController?

I'm running into a problem with an iPad app where I would like to have UINavigationControllers in both of the views within a UISplitView. I've looked through other similar questions here, but most link to a tutorial online that doesn't completely solve the problem. Here's a 2-minute walkthrough to re-create the problem I'm having:
Create a New Project in XCode, starting from the Split View-based Application template.
Add the following NSLog statement as the first line within the DetailViewController's willHideViewController method:
NSLog(#"toolbar: %#", toolbar);
If you run the application now, the log will show that the DetailViewController's toolbar is alive and well. Now...
Open MainWindow.xib and expand the SplitViewController.
Drag a Navigation Controller from the library on top of the DetailViewController.
Expand the new Navigation Controller and change the class of the UIViewController within to a DetailViewController.
Ctrl-drag from the SplitViewController to the DetailViewController and assign it as the delegate.
Save MainWindow.xib and run the app again.
At this point, the detail view has a navigation bar and an empty toolbar. If you view the logs, you should find that the toolbar is null. Why is this? Am I missing some sort of connection in Interface Builder? Is the navigation bar the problem for some reason?
Unlike the tutorial at http://www.cimgf.com/2010/05/24/fixing-the-uisplitviewcontroller-template/, I would like to keep both the navigation bar and the toolbar (preferably with the toolbar at the top when in portrait and not visible when in landscape), so that I still have a functional "Back" button when the iPad is in portrait orientation.
Does anyone have any suggestions for fixing this problem? An example project with this sort of set-up would be ideal.
You can certainly use a navigation controller on the detail view of a split view controller. In fact, the iPad Settings app uses this approach. Probably the best way to get this setup is to create a new project in Xcode 4.x and select the "Master-Detail Application" template. It will generate a split view controller with 2 navigation controllers, one for the left view and one for the right view.
To your toolbar question, to keep things simple I would put a toolbar in the bottom. You can still put bar button items on the top navigation bar, although you can only put them in the left, middle, or right. If you need lots of items on the top bar, one way is to add a toolbar to the detail view and hide the navigation bar in the viewWillAppear event of the detail view class.
Here is an example on how to hide the navigation bar and show the toolbar:
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.navigationController.toolbarHidden = NO;
self.navigationController.navigationBarHidden = YES;
}
I've found the built-in UISplitViewController to behave badly when trying to combine it with most of the other built-in view controller subclasses. Matt Gemmell's MGSplitViewController is a lot more flexible and has worked pretty well for me, despite the odd glitches (though those are at least fixable as the source code is provided).