I have a custom UINavigationController that supports auto-rotate. I also have a UIDatePicker on one of my views that I throw onto the stack of the Navigation controller. The auto-rotate works if I start the date picker view in portrait and then rotate it. If I try load the date picker view in landscape to begin with, the view is all messed up. It looks like it would if it didn't support rotation and the frame only has about half of the picker visible and off center.
I've tried making my own date picker that supports auto-rotate in case that was the problem, I've tried creating two different views and swapping them out, and I've tried changing the view frame size on the ViewWillAppear method. None of them seem to be working for me as of yet.
Anyone have any suggestions on how to get the date picker to show up in landscape correctly on a navigation controller? I probably am overlooking something simple and the answer is right in front of me, but I'm not finding it.
I ran into the same problem. When you load a view while already in Landscape orientation the UIPicker is not rendered correctly. I spent several hours trying to find a workaround until I found a fix from this page from Llamagraphics. You add this code in viewDidLoad of the view controller that has the picker:
for (UIView* subview in myPicker.subviews) {
subview.frame = myPicker.bounds;
}
Visit the webpage for more details. Thank you Stuart!
The below code will work for both portrait and Landscape mode. For this you need to set your tableview frame origin like that below:-
_dateTableViewCell=[self.tableView dequeueReusableCellWithIdentifier:#"DatePickerCell"];
if (self.dateTableViewCell==nil)
{
CGRect rect;
self.dateTableViewCell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:#"DatePickerCell"];
UIDatePicker *datePicker=[[UIDatePicker alloc]initWithFrame:frame];
datePicker.datePickerMode=UIDatePickerModeDateAndTime;
datePicker.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
CGRect cellRect = self.dateTableViewCell.frame;
cellRect.size.height = 216;
self.dateTableViewCell.frame = cellRect;
CGRect startRect = self.dateTableViewCell.frame;
startRect.origin.x = 0.0;
datePicker.frame = startRect;
[self.dateTableViewCell.contentView addSubview:datePicker];
}
Well I fixed it. I managed to make a check to see what the orientation was, and then remove the date picker and in code, I recreated a date picker and added it. That worked, it wasn't beautiful, but it worked.
Add date picker to view that is auto-rotated (controller's view, not directly in the window).
Set self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin
Here's what worked for me. When I create the DatePicker, I make it think it's in portrait mode:
[[UIApplication sharedApplication] setStatusBarOrientation: UIInterfaceOrientationPortrait animated: NO];
datePicker = [[UIDatePicker alloc] initWithFrame: CGRectZero];
[[UIApplication sharedApplication] setStatusBarOrientation: curOrientation animated: NO];
So basically, I change the orientation, create the datePicker, and change the orientation back right away to what it was before. I set the picker width (screen width) and height (216) elsewhere.
I got this clue from another page.
I had the same problem with displaying the date picker (in timer mode) resized horizontally on the iPad. I couldn't get any of the known solutions to this bug to work, so I fixed this with an ugly hack which involved putting two datepickers in the view - one is resized in the background, and the other is in standard size (320px) in the foreground... I know, sounds sick, but it displays properly and that's what counts. It's Apple's fault anyway ;)
Related
My app has a multi-pane tutorial-style view that users swipe through to learn about the app. This is implemented very much as described in this tutorial. Having implemented it for both iOS 7 and 8, I'm comparing how they work, and finding issues with the latter — I'm running Xcode 6 GM here.
It seems that the UIPageViewController is rendering the views after the transition is complete. I overrode the delegate methods to see what was going on:
- (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray *)pendingViewControllers
{
NSLog(#"Frame size before: %#", NSStringFromCGRect([(UIViewController*)pendingViewControllers[0] view].frame));
}
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{
NSLog(#"Frame size after: %#", NSStringFromCGRect([(UIViewController*)previousViewControllers[0] view].frame));
}
And here's a sample output:
Frame size before: {{0, 0}, {600, 600}}
Frame size after: {{0, 0}, {320, 568}}
This manifests like so: swipe to the left to pull in the next view, and note a 32-pt white space at the bottom of the new view. Once the transition is complete, it jerks into its proper layout.
Is this a bug in iOS 8, perhaps? I'm all out of guesses at this point.
I figured out you need to base your constraints on the view and not the layout guide of your view controller. This will ensure your view controller respects the constraints you set prior to the transition in a PageViewController.
you can do this like so:
Remember to uncheck "Constrain to margins"
For anyone having this issue, for me it appeared to be that I was laying out views "relative to margin" (a new feature in iOS 8).
Instead of:
Use:
I've been struggling with this for a few days.
I tried to implement it by instantiating the page ViewController from the storyboard. There was a definite resizing occurring. Checking the frame size in
pageViewController:viewControllerAfterViewController
pageViewController:willTransitionToViewControllers
pageViewController:didFinishAnimating:previousViewControllers
The frame size would always change between the calls to 1 and 3. Sometimes before 2 and sometimes after.
If you're also using storyboards, I was able to resolve the issue by extracting the page UI elements into its own XIB file, setting the constraints in IB and then creating the pages with a call to initWithNibName.
Not a complete answer but it returned me to feeling productive.
Hope it helps.
For me solution was to pin top of the tableView to superview:
Editor -> Pin -> Top Space To SuperView (iOS8)
It is a bug in iOS 8 but I found a workaround:
Add an empty view on top of the statusbar in your Storyboard. The height of the view should be as much as the y-value of your object that is being moved.
I'm currently migrating my app on ios 7 and I've been stuck for hours on the new navigationcontroller/bar management.
Before, when we had a navigation controller, we had a snippet like this :
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:[[MainViewController alloc]init]];
In interface builder, we had the choice to set an existing navigationbar for the view and everything match the content of the real view.
OK so now, i have no clue of how to design properly with interface builder.
I still have my snippet to initialize my navcontroller. However in the interface builder for my MainViewController if I set a status bar to translucent or opaque navigation bar, i have an offset of 44px at the top (see below).
Interface Builder_________________________And the result
Now, if i set status bar to none, there is no offset at top but since the view on simulator is smaller because of navigation bar the bottom of the view in interface builder is cut off.
Interface Builder_________________________And the result
I guess i'm really missing something here but i can't find any topic or apple info in iOS7 Transitions Guide about that.
Thanks for your help
EDIT
As we can see in the pictures, the first child of the view is a UIScrollView which contains both labels, the problem does not appear when there is no scrollview. It also appears if it's a UITableView.
If a label is outside the UIScrollView, there is no offset to that label.
OK so i found the solution, I have set in my controller the property:
self.automaticallyAdjustsScrollViewInsets = false
I don't really understand the true benefit of this property though, (or why the default value is true)
The only documentation i found was there:
https://web.archive.org/web/20160405135605/https://developer.apple.com/library/ios/documentation/userexperience/conceptual/TransitionGuide/AppearanceCustomization.html
https://developer.apple.com/documentation/uikit/uiviewcontroller/1621372-automaticallyadjustsscrollviewin
Update
In iOS 11 automaticallyAdjustsScrollViewInsets is deprecated
You should now use:
self.tableView.contentInsetAdjustmentBehavior = .never
I also encourage you to check this question and its answer to get a better understanding of those properties
#Justafinger's answer worked like a charm for me as well.
Just wanted to add that this setting can also be adjusted easily from the interface builder.
Select your view controller
Click the 'Attributes Inspector' tab
Uncheck 'Adjust Scroll View Insets'
Enjoy!
I was running into this same issue, but I found a rather odd property on the ViewController in interface builder that seems to have been causing this for me. There is an "Extend Edges" set of check boxes. I removed the "Under Top Bars" check, and everything started laying out properly for me.
With automaticallyAdjustsScrollViewInsets set to YES (the default setting) there is a mismatch in scrollview positioning between ios6 and ios7, so to make them consistent you need to disable this setting. However, ios6 will crash if it comes across automaticallyAdjustsScrollViewInsets, so you either need to make a programatic change of automaticallyAdjustsScrollViewInsets conditional on ios7 or else switch off the option using the storyboard/NIB
I had a similar problem, after dismissing a viewController, the contentOffset from my tableView was changed to (0, -64).
my solution was a little weird, I tried all the other answers but had no success, the only thing that fixed my problem was to switch the tableView position in the controls tree of the .xib
it was the first control in the parent View like this:
I moved the tableView right after the ImageView and it worked:
it seems that putting the table view in the first position was causing the trouble, and moving the table view to another position fixed the problem.
P.D. I'm not using autoLayout neither storyboards
hope this can help someone!
I also face this problem.
UIScrollView content size is calculate by OS as other sizes, origins provided by constraint system - that's why OS has doubtfulness.
How to fix - You should explicitly define content size of UIScrollView:
Embed scrollable content to UIView (I rename it to ContentView)
Add constraints:
ContentView.Weight = View.Weight and ContentView.Height = View.Height
It seems like a work around solution is to view the storyboard file as "iOS 6.1 and earlier" (select storyboard file->File inspector->Interface Builder Document->View As. Positioning subviews in this mode shows the offset.
Thank you guys for the solutions! I struggled for hours trying to solve the problem. Everything was ok when there was no Navigation Bar involved but it went haywire the moment I embedded the ViewController in a NavigationController.
I solved it by unchecking the Adjust Scroll View Insets and the Under Top Bars. Both of these are located in the ViewController's Attribute Inspector. Thanks a million!
Accepted answer by #streem caused some weird behavior with UILabel acting as sections.
This worked for me:
if let navBar = navigationController?.navigationBar {
scrollView.contentInset = UIEdgeInsets(top: -navBar.frame.size.height, left: 0.0, bottom: 0.0, right: 0.0)
}
Having recently switched to autolayout in Xcode 5 (and having watched the developer video from WWDC 13), I'm finding things to work pretty well with the exception of a View-Based NSOutlineView.
Before autolayout, this worked. Everything works fine and is in the right location, but now, specifically when I scroll, some of the new entries (and not all of them) end up in the wrong place, always larger and slightly higher.
The problem goes away once they are redrawn, but I don't understand the mechanic for drawing these NSTableCellViews and when they are created by the Outline View. I mean, it looks like they are created at some point, the program is guessing about the proper constraints, and then fixing them after a redraw.
It would be really nice to post an image to explain this, but can someone explain the life cycle of a view in an NSTableView or NSOutlineView?
I had to grapple with that issue myself and I was able to fix it today. This will happen if you are using any content inside an NSTableCellView that needs to be resized to fit into its cell or any subview of it. I fixed this problem by using an NSImage with the exact same size as a placeholder NSImage I added as subview to the NSTableCellView on IB. This resizing will break the constraints you added to or expect in this view.
So I have embedded a UITableViewController in a UINavigationController, all done in the Storyboard visual editor. Unfortunately, when my app runs, the table view extends underneath the nav bar, which looks bad and hides the pull-to-refresh control.
Any ideas how to fix this?
Known bug in iOS 7 beta 3 regarding UIRefreshControl :(
Several :-)
self.navigationController.navigationBar.translucent = NO;
or add in viewDidLoad:
CGRect frame = self.tableView.frame;
self.tableView.frame = CGRectMake(frame.origin.x, frame.origin.y+64,
frame.size.width, frame.size.height-64);
I'm practicing development of a simple iPad Split View app (Stanford's Hegarty online class). And everything works for the most part. However, the Master side ('left side), although working in landscape mode looks a little different than what I expect it to as a 'popover' in portrait mode. The 'popover' covers the left side of the screen including the toolbar button item that triggered it where normally it should not cover that button.
Unfortunately I can't post images so I'll try my best to describe in more detail. Normally the 'proper' popover will be hovering right below the bar item button that triggered it with a thick arrow-ish thingie (the 'anchor') pointing to the button and not covering that button. The popover can be dismissed by clicking on that button again (or elsewhere on the screen).
What's happening to me, however, is that when I click the bar item button to show the popover, the resulting popover 'covers' the button and essentially fills up the left portion of the screen (the detail view is under it and most of it is showing) with its designated width (so, again, it doesn't cover the entire detail view). The is no 'anchor' arrow pointing to the bar item button since it is obviously covering it instead. The popover is dismissed normally once I click anywhere else on the screen.
So why is my popover covering the button and not simply hovering under it with an 'anchor' pointing to it as it should?
I don't think it it makes much sense to post code at this point because I don't think it'll help and more importantly not sure what portion to post considering this might be a problem with how I wired it in the Builder. Any thoughts will be greatly appreciated!
Thanks!
Mo
I believe its a change that came in IOS5.1
If you want the same behaviour you probably need to set the master up as a popover segue, from a toolbar button or similar in the detail view, and set the split view delegate to not show the master in portrait.
I'm on the move now but if you want any more info let me know and I'll try and get back to you later.