Grouped UITableView space over header view - ios

I have a UITableView with a UITableViewStyleGrouped style. I also add a table header view (not section but table). The problem is that there is a space between the start of the table view and the header view.
self.tableView.tableHeaderView = myHeaderView;
Any idea how I can get rid of this? This does not happen if I use a UITableViewStylePlain style

I think you are set headerView frame in viewController.
Design tableView headerView in storyboard itself.
or If you are not using storyboard/XIB change the header height.
Hop it will solve your problem .

Add the following code in the viewDidLoad of the class
self.tableView.backgroundView = nil;

Use this line --
self.automaticallyAdjustsScrollViewInsets = NO;

Override the following delegate method of UITableView to disabled the default margin.
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 0.01; // Removed the section header margin. (couldn't be 0 here, weird)
}

Related

UITableView grouped hide section separator

I know this question has been asked before. But no person on the internet had a working and sufficient answer.
EDIT Obviously people don't read questions anymore, on SO. So I'm trying to clarify: I want to remove the SEPARATOR. The separator is neither the space above the section, nor the tableViewHeader or tableViewFooterView. It is only the thin line above (fully from left to right).
I have a grouped UITableView (I don't want to use a plain styled for many other reasons, take it as it is) which has multiple groups.
The first section should not have the separator line on top. Setting the separator style of the tableView is not an option, because I do need the other separators.
Setting the tableViews tableFooterView is something I often read, but it never worked.
I used the tableView with static content before and I was able to remove the separator in -[UITableViewController viewDidLoad] using this:
- (void)viewDidLoad {
[[[self headerTableCell] valueForKey:#"_topSeparatorView"] removeFromSuperView];
}
Since I now had to change the tableView to a dynamic one, the IBOutlet property won't work anymore (obviously).
So I tried everything, -[id tableView:willDisplayCell:atIndexPath:], -[UITableViewCell initWithStyle:reuseIdentifier:, prepareForReuse, awakeFromNib] and some others.
In any case, this separator is nil. So I need a method that gets called when the complete view hierarchy of the cell is setup.
what i get from your situation you have a grouped UITableView you want the first section without separator and you want to keep the separator in the other sections so
remove the separator from the whole tableview from the attributes inspector make Separator : None
create custom UITableviewCell in storyboard for other sections and add View at the end of it with height 1 and width the whole screen (like default separator)
it's maybe not the best idea but this will allow you to have the first section without separator
I faced a similar problem, wanted to remove the last line of the section in grouped table view, I am calling following method in view will appear and on every table reload. This is not the exact answer but problem can be solved by just changing y value of dummy view.
+(void)removeLastSectionSeparatorForTableView:(UITableView *)tableView
{
UIView *oldSeparatorView = [tableView viewWithTag:kTagDummySectionSeparator];
if (oldSeparatorView != nil)
{
[oldSeparatorView removeFromSuperview];
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(),
^{
UIView *view = [[UIView alloc] init];
view.tag = kTagDummySectionSeparator;
view.backgroundColor = [UIColor colorWithRed:239.0/255 green:239.0/255 blue:244.0/255 alpha:1.0];//Group table background color
view.frame = CGRectMake(0,
tableView.contentSize.height-40,
tableView.bounds.size.width,
2);
[tableView addSubview:view];
});
}
Maybe this problem is the same as mine before.
Finally, my way to solve this problem: set table view delegate's method (CGFloat)tableView:(UITableView *)tableView heightForHeaderAtSection:(NSInteger)section, then return CGFLOAT_MIN;
add this override function in your Custom Cell Class
override func layoutSubviews() {
super.layoutSubviews()
for subview in subviews where (subview != contentView && abs(subview.frame.width - frame.width) <= 0.1 && subview.frame.height < 2) {
subview.removeFromSuperview()
}
}

Is it possible to have a fixed uitableview Header while using sections?

This question should not be mixed up with this here.. These are two different things.
There is a good example how to use a UITableView Header on SO.
This all works fine and the main header is fixed on top as long as the style is set to plain.
But if I use sections, the main header no longer sticks to top and moves away while scrolling to the bottom.
In this method, I am returning the header for each section.
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
In this method I am setting the height for the header section above:
- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
In this method, I am setting the real table header.
- (void)viewWillAppear:(BOOL)animated {
...
self.recordTableView.tableHeaderView = headerView;
}
Is it even possible having a fixed table header, while using sections?
What is an alternative solution to this please?
If you want a UITableViewController (static cells/keyboard handling) and have a fixed header then you should use Containment. You can do this from a Storyboard by setting up a UIViewController with your fixed header and then using a Container View to embed the UITableViewController.
Once you have your containing view setup, you right-click drag from the Container View to the View Controller you want to embed - the UITableViewController in this case.
You can access and get a reference to the contained View Controller (the UITableViewController) from the Container View Controller by implementing the prepareForSegue:sender: method.
There’s no way to maintain the header of a tableView fixed, but
an useful approach when you need a unique header, is to use a UIViewController rather than a UITableViewController, and set the header (UIView) out from the tableView.
Something like this:
If you want to keep the class as a UITableViewController you can add your header as a subview to the tableview's superview. You will have to also push the tableview top inset down so your headerview doesnt hide the table.
Here is a sample code to put inside your tableViewController subclass (This example assumes your tableview controller is inside a navigation controller, so it pushes the view to below the navigation bar):
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.automaticallyAdjustsScrollViewInsets = NO;
}
-(void)addHeaderView{
CGFloat yPosition = self.navigationController.navigationBar.frame.origin.y + self.navigationController.navigationBar.frame.size.height;
mainHeaderView = [[UIView alloc] init];
const CGFloat mainHeaderHeight = 44;
[mainHeaderView setFrame:CGRectMake(0, yPosition, self.view.frame.size.width, mainHeaderHeight)];
mainHeaderView.backgroundColor = [UIColor redColor];
[self.tableView.superview addSubview:mainHeaderView];
[self.tableView setContentInset:UIEdgeInsetsMake(yPosition + mainHeaderHeight, self.tableView.contentInset.left, self.tableView.contentInset.bottom, self.tableView.contentInset.right)];
}
I haven't done this, but the first thing I would think to try is to place my tableview in a UIView and make my own header there in that UIView. Seems a trivial matter to make that view appear to be the header of the table and it would certainly stay put.

Custom header view overlapped by UITableView

In interface builder I have a header view above my UITableView, however in the simulator it is missing, and the Table View seems to be over it since it takes up most of the screen. Any reason for this? Work around?
Interface Builder
Simulator
In your case:
From your interface builder image I can see that table view is subview of view and you header view is also subview of tableview. It happening because tableview is hiding the header view. if you add the header view as subview of tableview then it would appear. But adding subview will not solve your problem because when you will scroll the tableview the subview will be gone.
For solving your problem as I can see that you have a navigation bar in your table view you can add the header view as subview of UINavigationBar.
[self.navigationController.view addSubview:headerView];
Good Practise:
Set the header view for section. Then you don't need to set any custom view at the top of your tableview. Try this:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *aView = [[UIView alloc] init];
//Customize the view according to our requirment
return aView;
}
Also implement this:
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 44.f; // Make this height as you need. Or else you may not see the full view.
}
Btw you can create a subclass of UITableViewController instead of UIViewController.
Hope this helps.. :)
Deselect Extend Edges / Under Top Bars

Adding UISearchBar into tableView header as subview

I'm trying to add a custom header to UITableView, that has some buttons and an UISearchBar.
The problem is, that when I try to use searchBar I get a message:
setting the first responder view of the table but we don't know its type (cell/header/footer)
Has anyone encounter such problem?
Are you adding to the table via:
[self.tableView addSubview:customView]
If so, that could be your error. Adding subviews to UITableView requires that you add them either as header, footer, or cell explicitly. Try:
self.tableView.tableHeaderView = customView
Just follow the simple steps here..
create a property for mySearchBar in your '.h' file and synthesize.
set its attributes in viewDidLoad/viewDidAppear method (or u can simply do it in the Interface Builder)
Use the following delegate method to set it as the header of your table view...
– (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
return self.mySearchBar;
}

How to remove header and footer space from a UITableView?

I have a UITableView in the grouped style, and only one section. However there is some blank space above and below the table view that is shown when the user scrolls too far. How can I remove this blank space?
You can do this by altering the contentInset property that the table view inherits from UIScrollView.
self.tableView.contentInset = UIEdgeInsetsMake(-20, 0, -20, 0);
This will make the top and bottom touch the edge.
Add this code:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 0;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
return 0;
}
Actually this question answered my question.
Reducing the space between sections of the UITableView.
UIView can be inserted at the top and bottom of the table(drag and drop). Set their properties as transparent and height of 1 px. This is to remove the extra padding in front of the cells.
you can also use this code for removing space between first cell of uitableview..
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 0.002f;// set this...
}
Uncheck Extend Edges Under Top bar.
This answer comes quite late, but I hope it helps someone.
The space is there because of the UITableView's tableHeaderView property. When the the tableHeaderView property is nil Apple defaults a view. So the way around this is to create an empty view with a height greater than 0. Setting this overrides the default view thereby removing the unwanted space.
This can be done in a Storyboard by dragging a view to the top of a tableView and then setting the height of the view to a value of 1 or greater.
Or it can be done programmatically with the following code:
Objective-C:
CGRect frame = CGRectZero;
frame.size.height = CGFLOAT_MIN;
[self.tableView setTableHeaderView:[[UIView alloc] initWithFrame:frame]];
Swift:
var frame = CGRect.zero
frame.size.height = .leastNormalMagnitude
tableView.tableHeaderView = UIView(frame: frame)
Comments
As others have noted you can use this same solution for footers.
Sources and Acknowledgements
See the Documentation for more details on the tableHeaderView property.
Thanks to #liushuaikobe for verifying using the least positive normal number works.
My original answer: https://stackoverflow.com/a/22185534/2789144
In my case issue was with the constraints i was applying. I have to change them in order to show 2 rows in my case while bottom of table touching last row.
Use the bounces property of UIScrollView:
[yourTableView setBounces:NO];
This will remove what seems to be an extra padding at the top and bottom of your UITableView.
Actually, it will just disable the tableview's scrollview to scroll past the edge of the content.

Resources