I'm having this issue with several screens in my app, but I'll explain what happens to my home screen. Hopefully the solution isn't as complicated as I'm thinking it will be. So my home screen has a logo at the top, a label(title) under that, 3 horizontal buttons under that, and finally, settings and info buttons in the bottom left and right hand corner respectively when if portrait orientation. In order to allow for landscape orientation, resizing masks were not able to achieve the look I wanted so I implemented the
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
method with an if and else statement, the "if" uses CGRectMakes to draw all of the elements where they should go in landscape layout, and the "else" redraws them back to their original places when changed back to portrait landscape. This all works very nicely. I remembered that we had to be able to handle the double high status bar, so I simulated it to see what it would do to my app. When I am on the home screen and toggle it on and off, the autoresizing of the items(which are set to adjust according to the top of the view) work nicely, by slightly squishing everything down a bit, and not hiding anything. I can toggle it off and on with no problems.
Now here's the problem:
When I have the double high status bar toggled on while on a different screen, then go back to my home screen, the resizing doesn't happen, and it redraws my screen full size according to the coordinates and sizes I have in the method I mentioned earlier, so the settings and info button are drawn halfway off the bottom of the screen. Same happens when switching from landscape back to portrait on the homescreen with the double high status bar already on.
Similarly, I have a map between a nav and tab bar on another page. When already on the page, and toggling it on and off, everything resizes nicely(the frame of the map changes height and the nav bar moves down). But again, I have a problem when switching to that screen from a different screen or from the landscape orientation, because instead of autoresizing appropriately, the map view and nav bar get pushed down behind the tab bar partially, obscuring the google trademark which is grounds for app rejection.
Sorry for the longwindedness, but I wanted to clearly describe what circumstances cause this problem. Any ideas would be greatly appreciated as I don't really have any idea how to approach this.
I've been trying to track down this problem myself. I think this happens because the autoresizing mask is only used when views are resized, and not when a new view is added to the scene.
For me, I wanted a settings view loaded from a nib and added on top of everything else. If the double-height bar was in effect when the view was added it would run off the bottom of the screen. To fix it you have to set the size and position of the view yourself when you load it. This is the code behind my working 'goto settings' button:
- (IBAction) settingsPressed:(id)_sender
{
NSArray* a = [[NSBundle mainBundle] loadNibNamed:#"SettingsView" owner:self options:nil];
SettingsView* settings = [a objectAtIndex:0];
settings.frame = self.view.bounds;
[[self view] addSubview:settings];
}
The important line being:
settings.frame = self.view.bounds;
Which, it would appear, classifies as a 'resize' and so the resizing-mask rules apply. I later added animations for the transition and it continues to work just fine.
Note: This method was in a View Controller.
Related
I have a 'UIScrollView' that is supposed to display a list of images one next to the other. This is the code I'm using to add each image:
#define SCROLL_PADDING 10
#define SCROLL_DIMENSIONS 50
view.frame = CGRectMake(xValue, SCROLL_PADDING, SCROLL_DIMENSIONS, SCROLL_DIMENSIONS);
[scroller addSubview:view];
However, as shown in the image below, the images are loaded with a vertical offset. After some research I realised that this offset is the same as the height of the navigation bar's height.
Note 1: By default the images cannot be seen. I had to scroll up to make them visible.
Note 2: I shouldn't be able to scroll because the images should fit in the scroll view.
I decided to present the view controller modally instead of pushing it to the hierarchy of the navigation view controller and everything work as expected.
This problem only happens in iOS7. Any ideas why?
I came across this article, which clearly explains various changes in status bars and navigation bars on iOS7
As you can see in both of the images above, the position of the scroll view doesn't change. In iOS6 if the subview's frame doesn't change, it would be moved down to prevent it from underlapping the navigation bar. Since iOS7 it is expected that all subviews will underlap not only the navigation bar but also the status bar, which makes the location (0, 0) the top left of the SCREEN.
For some reason that I don't understand yet (it would be nice if somebody could explain), only the scroll view's subviews where moved down in the same way it was being done in iOS6. Hence making the subviews appear out of the scroll view's bounds.
To prevent the subviews from underlapping the navigation bar it is necessary to set edgesForExtendedLayour to UIRectEdgeNone as early as possible in the life cycle of the view controller
viewController.edgesForExtendedLayout = UIRectEdgeNone;
I am in the process of transitioning an app to iOS7. All of the views throughout the app have a 44px empty space at the bottom that appears to be for a bottom toolbar or something, but I am not trying to display a bottom toolbar. This space also exists on views that do have a bottom toolbar and the toolbar just shows directly above it.
The red space shown is actually a view behind the black view. No matter what size I set the frame of the black view to, the red space is always shown. I am also hiding the status bar in plist, so don't know if this is an artifact from that or if it has something to do with navigation bar as they are both normally 44px in height.
I have looked at the transitioning guide and haven't found anything that's worked. Any ideas to what could be causing this and how to fix?
UPDATE:
I have tried setting edgesForExtendedLayout = UIRectEdgeAll and extendedLayoutIncludesOpaqueBars = YES (also tried NO) with no effect. When I look at the subviews of the navigation controller it shows a UIToolBar as hidden, but shows it contains a frame in the exact area the view refuses to resize to even with autolayout constraints.
UPDATE 2:
This is actually a problem with ViewDeckController (https://github.com/Inferis/ViewDeck) and the way it sets it's center view bounds.
I believe it has to do with the UINavigationBar. Try toggling the following options in Storyboard and see if it solves the problem. Namely, the 'Extend Edges' options:
These options can also be set in code with the edgesForExtendedLayout and extendedLayoutIncludesOpaqueBars properties on UIViewController.
If you are transitioning to iOS 7, you should be using an Auto Layout constraint to anchor to the Bottom Layout guide. Control drag from your view to the Bottom Layout guide and choose Vertical Space from the popup menu.
Using frames in iOS 7 is harder and is the way of the past.
Auto Layout is hard to grasp at first, but it is very powerful once you get the feel.
This is actually a problem with third party library ViewDeckController (https://github.com/Inferis/ViewDeck) and the way it sets centerViewBounds for IIViewDeckControllerIntegrated. I was able to figure it out after changing to IIViewDeckControllerContained and seeing the view sized correctly.
In IIViewDeckController.m, just return self.referenceBounds for iOS7 like it does for IIViewDeckControllerContained.
Bit of a strange one.
I have a UIButton which works when located anywhere on the view except the top left hand corner when in landscape mode.
I have a navigation bar with a back button nested in the same area but when the the video enters full screen and playback state changes this navigation bar is hidden.
any ideas?
As thought, the problem was occuring due to the hidden navigation bar and the navigation item located in the same place.
The only solution i can find was to remove the navigation bar from superview then add it back when needed.
Your view's hierarchy is not properly configured. To properly configure your hierarchy, you need to navigate to either the xib or storyboard that you're working with, and re-order the button so that it's on top of anything that falls within it's similar bounds. A common example is that you added a UIView, which is clear, and you had the button underneath it, and now you can't interact with it even though you can't see it.
I have a UITabBarController displaying a number of settings-screens in my app. I want them to be shown on just a part of the screen for layout reasons. In fullscreen, the lists become unreadable (too wide), there are just a few controls per page making the page feel very empty, and the tabbar buttons are far away from the content (Fitts law).
Using presentModalViewController with the UIModalPresentationFormSheet style gives me the size I want. I do this on top of an empty background, since in my case it doesn't make sense to display anything behind it. The "real" working area is displayed with another presentModalViewController in fullscreen mode on top of it all.
This works but feels like a hack. One problem is, I can't make the background behind the settings dialog move in the transition to fullscreen with the UIModalTransitionStyleFlipHorizontal style.
TL;DR
Can I embed a UITabBarController non-fullscreen in another "background"-view? I can't find any information of how I would do this.
Can I embed a UITabBarController non-fullscreen in another "background"-view? I can't find any information of how I would do this.
Why don't you try it out?
Create a container view of the size you want the tab bar controller to have.
Create the tab bar controller.
[containerView addSubview:tabBarController.view];
I’ve got a view that has to be presented both in landscape and portrait. The transition between different orientations is done by repositioning and resizing the subviews. One of the subviews is a button (plain UIButton with an image background). When the interface rotates to landscape, the button starts misbehaving – it can only be tapped on its left part, the right part does not respond. When I move the button a bit to the left, the tappable part grows. The button should not be obscured by any other view, it’s clearly visible. When I override the hitTest:withEvent: method in the parent view, I see that the taps in the “numb” part of the button result in nil being returned. I think I have seen this behaviour once before, but unfortunately I’ve forgotten the source of the problem :) Any help?
Ah yes, I forgot to resize the view itself. Thus the button was on the boundary of the view and even though it was not clipped, the part lying outside the view frame was not considered for hit tests.