I am currently working on an iPhone App. I now have a problem with the top spacing inset of a UITableView. See this screenshot:
There should be no space between the table view cells and the buttons.
I do not know how to fix this. The UITableView is embedded in a ContainerView like this:
I think I got the container view constraints right. Top Space to Chapter Button is set to 0.
I tried to change some settings of the table view controller in storyboard. For example the Adjust Scroll View Insets. However it does not change anything when I disable that.
I also tried to set the TableView insets directly in the code in viewDidLoad():
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
However this also did not fix it.
Can anyone help? I have no idea where to look.
This can be solved by disabling auto adjustment of scroll view insets. However this setting has to be applied to the ViewController which contains the ContainerView (with the UITableView inside of it). It does not work when applied to the UITableView itself.
This can be done via Storyboard:
Or via code in viewDidLoad(): self.automaticallyAdjustsScrollViewInsets = false
Since iOS 15 there's a new parameter which can introduce a top gap when using a section header. This can be removed with the following:
if #available(iOS 15, *) {
tableView.sectionHeaderTopPadding = 0
}
Try this Hope this work.
hide View which contains the ContainerView.
self.automaticallyAdjustsScrollViewInsets = NO
Related
I have subclassed UINavigationBar and customised the height of navigation-bar. Now it has 108pt height. But in all the screens, I am having the top area of tableview/scrollview behind the custom navigation-bar. I have tried extend edges under top bar, but it only move 64pt.
Is there any way to move all the contents below the custom navigation bar, without modifying top constraint or setting content insets of every screen?
Did you try -
automaticallyadjustsscrollviewinsets = false
This can be done from storyboard as well as from code.
Also, try setting your navigation bar to opaque.
Hope this helps.
First of all i would avoid to change the height of the apple navigationBar. This can cause some more problems. As you can see.
Anyway you could change the contentInset of the tableView.
tableView.contentInset = UIEdgeInsets(top: HEIGHTOFNAVIGATIONBAR - ADDEDHEIGHT, left: 0, bottom: 0, right: 0)
I have this arrangement in Interface Builder, all properties are set to zero.
However, when I run it on both device and simulator it appears like this
Where is the space above the cells come from?
So I try to set these properties for UICollectionViewFlowLayout in code like this
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.headerReferenceSize = CGSizeZero;
layout.footerReferenceSize = CGSizeZero;
layout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0);
layout.minimumInteritemSpacing = 0;
layout.minimumLineSpacing = 0;
layout.itemSize = CGSizeMake(103, 119);
self.calendarView.collectionViewLayout = layout;
but I have no luck.
How can I get rid of that space?
UICollectionView is descendant of UIScrollView class which has contentInset property, setting -20 top inset fixes the problem
[self.calendarView setContentInset:UIEdgeInsetsMake(-20, 0, 0, 0)];
However, the problem comes from UIViewController's automaticallyAdjustsScrollViewInsets property.
By documentation:
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.
That's why we get adjusted content insets for status bar. It's better to disable automatically adjusting than manually set value which doesn't match in result picture.
[self setAutomaticallyAdjustsScrollViewInsets:NO];
Another way is to select your ViewController and uncheck the checkbox Adjust Scroll View Insets in your interface builder:
It is essentially the same as the following line of code. But you got to see your changes right away in the interface builder.
automaticallyAdjustsScrollViewInsets = false
iOS 11 deprecated the use of automaticallyAdjustsScrollViewInsets, so the use of collectionView.contentInsetAdjustmentBehavior = .never is advised.
Here is the answer in swift with a few adjustments:
I have a collection view that takes up a small portion of the view. I used:
self.automaticallyAdjustsScrollViewInsets = false
to remove the top spacing that was messing up my layout. This piece of code didn't work for me:
self.paperCollectionView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
And neither did this one:
self.paperCollectionView.contentInset = UIEdgeInsetsMake(-20, 0, 0, 0)
But that might be because I'm not using a UICollectionViewController, I'm just using a UICollectionView.
Here's a bigger portion of the code to give more context:
You can also go with
[self.calendarView setContentInset:UIEdgeInsetsMake(0, 0, 0, 0)];
[self setAutomaticallyAdjustsScrollViewInsets:NO];
There is by default collection view header scrolling space added on the collection view and you do not need to add -20 from top because it may reflect on device issue
You can do this in Interface Builder by going to the Scroll View section and changing the Content insets dropdown to "Never".
Swift 3:
self.automaticallyAdjustsScrollViewInsets = false
This answer is weird, but it works if you are working in Interface Builder and have a Collection View embedded in a View Controller that is under the control of a Tab Bar Controller that is the root view controller of a Navigation Controller.
Add a Toolbar to the View Controller that has the Collection View
Move the Toolbar in the hierarchy such that it is above the Collection View
If the Toolbar is above the Collection View, there will be no space from the top of the prototype Collection View Cell to the Collection View. If there is no Toolbar or the Toolbar is below the Collection View, then there will be space between the top of the Collection View and the Collection View Cell. This is true both in the Storyboard preview and while running the app. The same type of thing occurs for Table Views.
This was most recently tested with Xcode Version 8.3.3
I have to show an UIMapView behind an UITableView into a controller in a way that the mapView becomes visible "behind" the tableview's header (similar to foursquare's "nearby places" view) with the typical parallax effect.
I've laid out my tableview within storyboards, added the mapView as a Container View behind the tableView, I've tried this in two ways: via storyboard and programmatically with something like:
[self.view addSubview: self.mapView];
[self.view sendSubviewToBack:self.mapView];
but in both cases the tableview's header ends under the navigation bar, I suppose by losing its reference to the toplayoutguide.
this is a screenshot of the view in storyboards:
and this is the result on the simulator:
As you can see, tableview's header starts under the navigation bar and not under the topLayoutGuide as it should.
Now, if I don't add any subview behind the tableview anything seems to work as expected, but I need the map behind so it is no use.
I've found a workaround with this code snippet placed into viewDidLayoutSubviews:
-(void)viewDidLayoutSubviews {
if ([self respondsToSelector:#selector(topLayoutGuide)]) {
UIEdgeInsets currentInsets = self.tableView.contentInset;
self.tableView.contentInset = (UIEdgeInsets){
.top = self.topLayoutGuide.length,
.bottom = currentInsets.bottom,
.left = currentInsets.left,
.right = currentInsets.right
};
}
}
But, it seems too much of a hack in first place, and also, tableview's contentInset starts at -64, not a big mess but I just don't like it.
My question so far is: why is this all happening and how can I fix it, if possible, in a more precise way?
I have dragged a plain jane UITableView onto a UIViewController in iOS 7.
Now there is an vertical offset of space before the first cell starts. How do I get rid of it? I want the first line to be much closer to the top edge of where the UITableView actually starts. I did not ask for the large offset did I?
Any ideas?
The new iOS 7 implementation of UIViewController has a new set of options that allows the developer to choose if the system will automatically add insets for UIScrollView, UITableView and derivations.
To disable this behaviour uncheck these boxes for all your wanted UIViewControllers in InterfaceBuilder, on UIViewController selected object inspector:
For more details:
Submit your iOS 7 apps today.
iOS 7 UI Transition Guide > Appearance and Behavior
By default table view controllers will pad the content down under the nav bar so you could scroll the content under it and see it, in a blurred state, underneath the navbar/toolbar.
Looks like you're positioning it at 44 (maybe 64)px to move it out from under the nav bar, but it already compensates for this so you get a big gap.
Go to the storyboard/xib in IB and untick the show content under nav bar stuff.
From iOS7 transition guide:
If you don’t want a scroll view’s content insets to be automatically
adjusted, set automaticallyAdjustsScrollViewInsets to NO. (The default
value of automaticallyAdjustsScrollViewInsets is YES.)
self.automaticallyAdjustsScrollViewInsets = NO;
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!
it resolve my similar problem:
if ([[UIDevice currentDevice].systemVersion floatValue] >= 7){
tableView.contentInset = UIEdgeInsetsMake(-20, 0, 0, 0);
}
Try using this
tableView.separatorInset = UIEdgeInsetsZero;
Obviously, if you're supporting anything less than iOS7 you will need to ensure that the object responds to this selector before calling it.
Seriously, changing contentOffset is not the solution. You're just patching a problem and not fixing the cause. I've been facing the same problem and it turns out that grouped tableViews have a padding on the top. In my case setting the type to plain has done the trick.
Hopefully it saves someone a few minutes.
Z.
With iOS 9, none of the other answers from this page worked for me (i.e. unchecking boxes in Storyboard, setting automaticallyAdjustsScrollViewInsets to NO).
My workaround I am really dissatisfied about was this:
- (void)viewDidAppear:(BOOL)animated {
self.tableView.contentOffset = CGPointMake(0.0, 0.0);
self.tableView.contentInset = UIEdgeInsetsMake(0.0, 0.0, 0.0, 0.0);
}
The same lines in viewWillAppear or viewDidLoad were ineffective.
Sometimes, I get a 64 height gap at the top of my Table View when the UIViewController is embedded inside a Navigation Controller.
In the past, I would just re-create everything, hoping that the constraints turn out correct after a clean slate.
TIL: If you don't want to make a vertical constraint to the Top Layout Guide, you can hold down the Option key to access the Container Margin.
Then make sure the Top Space to Superview constant is set to 0. This worked for me at least.
THis works for me:
- (void)loadView
{
[super loadView];
[self setAutomaticallyAdjustsScrollViewInsets:YES];
self.edgesForExtendedLayout = UIRectEdgeNone;
self.view.frame = CGRectZero;
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
}
If you add an empty UIView before UITableView (or any view is scrollable such as ScrollView and TextView), you can have a luck.
I had a UITableViewController embedded in a container view. To get rid of the unwanted 64 points of vertical space, I needed to uncheck the 'Adjust Scroll View Insets' in Interface Builder and set the UITableView's contentInset in my UITableViewController's viewWillAppear as below.
The size of the vertical space appears to match the navigation bar's frame height and y offset. The problem only occurred on iOS 7.
- (void)viewWillAppear:(BOOL)animated;
{
[super viewWillAppear:animated];
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
const CGRect navBarFrame = self.navigationController.navigationBar.frame;
const CGFloat blankVerticalSpace = navBarFrame.origin.y + navBarFrame.size.height;
self.tableView.contentInset = UIEdgeInsetsMake(-blankVerticalSpace, 0, 0, 0);
}
}
In Xamarin iOS, I had this issue occuring on a backgrounded UITableViewController just after the foreground modal dialog was being dismissed. In the process of moving into the foreground, the UITableViewController had insets set (somewhere by iOS):
This class solved it
public class UITableViewControllerWithBugFix : UITableViewController {
public UITableViewControllerWithBugFix(UITableViewStyle withStyle) : base(withStyle) {
}
public override void ViewWillLayoutSubviews() {
if (TableView.ContentInset.Top != 0.0f)
TableView.ContentInset = UIEdgeInsets.Zero;
if (TableView.ScrollIndicatorInsets.Top != 0.0f)
TableView.ScrollIndicatorInsets = UIEdgeInsets.Zero;
base.ViewWillLayoutSubviews();
}
}
From time to time I get back to this awful situation, and I notice that it's still quite unknown. So, for future memory...
Lately, I'm fixing with this workaround.
Add a subview at the top of the UITableView, with zero pixel height. Works with Autolayout or without.
If I feel confident :-) I remove this fake view, fix the constraints on the top, and magically it works.
Don't ask me why, I still think it's a bug deep in UIKit.
If you go to storyboard, you can change the offset by selecting the table and under the Table View section in the Attributes inspector you just change the Separator Insets on the left to 0.
I think the real solution is to set up your top and bottom constraints on the tableview be equal to the topMargin and bottomMargin. Not the top layout guide and bottom layout guide. This allows you to keep automaticallyAdjustsScrollViewInsets to be true.
Swift 3 solution:
class PaddingLessTableView : UITableView
{
override func headerView(forSection section: Int) -> UITableViewHeaderFooterView?
{
return nil
}
override func footerView(forSection section: Int) -> UITableViewHeaderFooterView?
{
return nil
}
}
If you embedded your TableViewController in a NavigationController or a ContainerView, You have to constraint to margins instead of top Layout guide in Storyboard. Check constraint to margins when you are doing the constraints No other way worked for me. I couldn't comment so I'm just reiterating on Robert Chens answer.
I tried several of the answers. Changing the settings in storyboard caused ripple problems with an overlay menu that pops in from the left.
I only have a blank UIViewController in storyboard, otherwise everything is programmatically generated.
I have same problem with a UITableView inside a UIView inside a UIViewController. Namely, the section headers start too far down when the UIViewController is embedded in a Navigation Controller. W/o the navigation controller everything works fine.
To fix the problem I created a UILabel and with constraints placed the UILabel bottom constraint = the top constraint of the UIView (so it does not show on the screen. Now with that additional control (the new Label) the TableView behaves properly.
inputsContainerView.addSubview(titleLabel)
inputsContainerView.addSubview(tableView)
// inputsContainerView
///////////////////////////////////////
inputsContainerView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
inputsContainerView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0).isActive = true
inputsContainerView.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -40).isActive = true
inputsContainerView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.7).isActive = true
// tableView
///////////////////////////////////////
tableView.centerXAnchor.constraint(equalTo: inputsContainerView.centerXAnchor).isActive = true
tableView.topAnchor.constraint(equalTo: inputsContainerView.topAnchor).isActive = true
tableView.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor).isActive = true
tableView.heightAnchor.constraint(equalTo: inputsContainerView.heightAnchor).isActive = true
// titleLabel - inserted to stop bad section header behavior
///////////////////////////////////////
titleLabel.centerXAnchor.constraint(equalTo: inputsContainerView.centerXAnchor).isActive = true
titleLabel.bottomAnchor.constraint(equalTo: inputsContainerView.topAnchor).isActive = true
titleLabel.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor).isActive = true
titleLabel.heightAnchor.constraint(equalToConstant: 20).isActive = true
I had a same problem in iOS 11 and xib, UITableviewController and I solved it as below
[self.tableView setContentInset:UIEdgeInsetsMake(-44,0,0,0)];
If none of the above answers work, try changing the table view style to plain from grouped
I need to add some blank space to the top of my UITableView that does not affect the size of the content area. Shifting the content down or adding a blank cell is NOT what I want to do. Instead I just want an offset.
How?
I'm not sure if I'm following you but I think I'm having the same predicament. In my case I must give some space to the ADBannerView at the top of the screen so what I did was in the viewDidLoad method I added:
[self.tableView setContentInset:UIEdgeInsetsMake(50,0,0,0)];
the values it takes are UIEdgeInsetsMake(top,left,bottom,right).
Alternatively the same with Swift:
self.tableView.contentInset = UIEdgeInsetsMake(50, 0, 0, 0)
Swift 4.2:
self.tableView.contentInset = UIEdgeInsets(top: 50, left: 0, bottom: 0, right: 0)
Swift 5.1
add the following in viewDidLoad
tableView.contentInset.top = 100
Really that's all there is to it.
override func viewDidLoad() {
super.viewDidLoad()
tableView.contentInset.top = 100
}
You can add an "empty" header view to the table... this would give the initial appearance of the table to have an offset, but once you started scrolling the offset would be gone. NOt sure that's what you want.
If you need a permanent offset and are not already using section headers, then you could create the offset similarly to above by making custom views for the section headers, especially if you just have one section, this could give you the look of a permanent offset.
I can post sample code if it sounds like either of those are what you are looking for.
I combined Jigzat's answer with:
[self.tableView scrollRectToVisible:CGRectMake(0, 0, 320, 1) animated:NO];
in
- (void)viewDidLoad
so the first cell isn't at the top.
Sounds like you want to wrap a 'View' around your UITableView. If you have a UITableViewController in IB the UITableView will automatically be set to the view of UITableViewController. You change view property to a normal UIView and add your UITableView in there and give it a offset.
---Edit---
I just read my post and thought it made little sense :) When you create a UITableViewController you get this (in pseudo code):
UITableViewController.view = UITableView
This means that the actual table will take up the whole space and you cannot even add other views. So you need to change the
UITableViewController.view = UIView
and add your table to that UIView
I combined this answer with this one:
https://stackoverflow.com/a/9450345/1993937
To make the tableView appear at the top of the content inset, so the space at the top isn't cut off by having the tableView scrolled down slightly when the view initially appears. (18 is my top gap)
[self.tableView setContentInset:UIEdgeInsetsMake(18,0,0,0)];
[self.tableView setContentOffset:
CGPointMake(0, -self.songListTable.contentInset.top) animated:YES];