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);
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 am working on a custom control box (that min,max/restore/close button in the top right of your Windows titlebar) for my new application. I use closeIcon = style.standardIcon(QStyle.SP_TitleBarCloseButton) to get the correct icon for them. See the full code here in my other SO question. What I got is a black icon. In which I need the white version when it's in hover state.
Can we .. I don't know, inverse it? Or should I get another icon from QStyle?
This question (and several others) are from the intention of creating a chrome like tab in PyQt application, by hiding the titlebar and reimplementing control box. But it didn't gives the best result. Right now this is my solution to create a chrome like tab in PyQt application. Therefore, I close this question.
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)
}
Why?
And sometimes there's this:
Is it a bug? Is there a fix? I just dragged a button and a textfield to the view controller.
That's odd, few things that come to my mind
Check if you're using autolayout or 'auto resize subviews'
Check if you programmatically do any layout
Check if you're working with portrait/landscape orientation
I doubt it's a bug, such an obvious problem would have been fixed by now
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 ;)