How to do large tableView header? - ios

I want to do a large tableView header like in Health app in iOS 11. I added a screenshot to show this element in red text. How to do large a tableView header?

If I understand your question correctly (and unfortunately the screenshot is gone), you can do that using the prefersLargeTitles property. This works on iOS 11 and higher only.
For instance:
if (#available(iOS 11.0, *)) {
self.navigationController.navigationBar.prefersLargeTitles = YES;
self.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeAlways;
} else {
// Fallback on earlier versions
}
You can call this code in viewDidLoad or viewWillAppear of your UITableViewController.

Just set the frame property of the tableHeaderView.

No recorded Data is table view header. you can customize the tableview header with viewForHeaderInSection method of tableview. Your question is already answered in this link. Changing Font Size For UITableView Section Headers

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UILabel *TESTLabel = [[UILabel alloc] init];
TESTLabel .frame = CGRectMake(20, 8, 320, 40);
TESTLabel .font = [UIFont boldSystemFontOfSize:18];
TESTLabel .text = [self tableView:tableView titleForHeaderInSection:section];
UIView *headerView = [[UIView alloc] init];
[headerView addSubview: TESTLabel];
return headerView;
}
TRY THIS

Related

Why is my tableview header showing up off-center?

iPhone 6 simulator:
iPhone5 hardware:
Channel Header:
- (id)initWithFrame:(CGRect)frame title:(NSString *)title {
self = [super initWithFrame:frame];
UILabel *l = [[UILabel alloc] initWithFrame:frame];
l.textAlignment = NSTextAlignmentCenter;
l.backgroundColor = BGC;
l.text = title;
[self addSubview:l];
return self;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
ChannelHeader *h = [[ChannelHeader alloc] initWithFrame:CGRectMake(0, 0, self.tv.frame.size.width, 44) title:[self titles][section]];
return h;
}
Why is my tableview header's textfield showing up off center?
Tableview frame in iPhone6 sim:
<UITableView: 0x7fce2c821a00; frame = (0 0; 414 736)
EDIT:
so I changed my simulated nib size from "iPhone 6" to "inferred", and the view boundaries grew. I stretched my UITableView to fit the bounds and now the text is even more off-centered. So somehow it's getting the wrong values for its frame..
Well, your frame for iPhone 6 is wrong.
iPhone 6 screen size is 375 x 667 points.
iPhone 6 plus screen size is 414 x 736 points.
Therefore, if you are running the application on iPhone 6 simulator and tableView frame is giving you iPhone 6 plus boundaries, then that is the error. Your header and UILabel is being rendered correctly according to the given frames.
So if you run your application in iPhone 6 plus simulator, you will get correct results.
More info on frames.
Solution:
If your setting your tableView through nib, and if you are using AutoLayout then you need to apply constraints accordingly.
If you have disabled AutoLayout then apply proper resizing masks to your tableView, i.e. Flexible Height & Flexible Width
Also, it would be a good practice, if you take values of the tableView frame provided by the delegate method instead of referring to the tableView property.
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
ChannelHeader *h = [[ChannelHeader alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(tableView.bounds), 44) title:[self titles][section]];
return h;
}
Note: This is just a piece of good practice and it doesn't effect the logic or the answer.
Whilst I await your response on the above comment, I'm quite certain I know why you are having an issue.
If you want to create UITableViewCell(s) which have centred labels there are really only two correct ways.
Either:
Subclass UITableViewCell and create a custom subclass which has an indigenously centred label.
Set the NSTextAlignment of the regular UITableViewCell textLabel control to centre in cellForRowAtIndexPath like so: cell.textLabel!.textAlignment = .Center.
To change the header text alignment, you should do something like this:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UILabel * sectionHeader = [[UILabel alloc] initWithFrame:CGRectZero];
sectionHeader.backgroundColor = [UIColor clearColor];
sectionHeader.textAlignment = NSTextAlignmentCenter;
sectionHeader.font = [UIFont boldSystemFontOfSize:10];
sectionHeader.textColor = [UIColor whiteColor];
return sectionHeader;
}

Hide remove separator line if UITableViewCells are empty [duplicate]

This question already has answers here:
Eliminate extra separators below UITableView
(34 answers)
Closed 6 years ago.
I have a UITableView and I have only 3 rows in it, and I can see those 3 rows. The problem is the cells that are empty: I can see lines there. I don't want to see those lines.
Any idea how to remove those lines?
Below is image for what I am looking for.
Even simpler than Andrey Z's reply:
Simply make a bogus tableFooterView in your UITableView class:
self.tableFooterView = [UIView new]; // to hide empty cells
and Swift:
tableFooterView = UIView()
You can hide UITableView's standard separator line by using any one of the below snippets of code.
The easiest way to add a custom separator is to add a simple UIView of 1px height:
UIView* separatorLineView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 1)];
separatorLineView.backgroundColor = [UIColor clearColor]; // set color as you want.
[cell.contentView addSubview:separatorLineView];
OR
self.tblView=[[UITableView alloc] initWithFrame:CGRectMake(0,0,320,370) style:UITableViewStylePlain];
self.tblView.delegate=self;
self.tblView.dataSource=self;
[self.view addSubview:self.tblView];
UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 10)];
v.backgroundColor = [UIColor clearColor];
[self.tblView setTableHeaderView:v];
[self.tblView setTableFooterView:v];
[v release];
OR
- (float)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
// This will create a "invisible" footer
return 0.01f;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
// To "clear" the footer view
return [[UIView new] autorelease];
}
OR
And also check nickfalk's answer, it is very short and helpful too.
And you should also try this single line,
self.tableView.tableFooterView = [[UIView alloc] init];
Not sure but it's working in all the version of iOS that I checked, with iOS 5 and later, up to iOS 7.
Updated answer for swift & iOS 9. This works for tableviews of the .Plain variety.
tableView.tableFooterView = UIView()
Transparent UIView as a tableView footer with 1px height will do the trick.
UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 1)];
v.backgroundColor = [UIColor clearColor];
[self.tableView setTableFooterView:v];
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
Use this Code for remove separator line for empty cells.
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
// This will create a "invisible" footer
return 0.01f;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
return [UIView new];
// If you are not using ARC:
// return [[UIView new] autorelease];
}
Just returning an empty UIView() in viewForFooterInSection worked for me:
override func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
return UIView()
}
Please try the following code:
self.tblView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
if ([self.tblView respondsToSelector:#selector(setSeparatorInset:)])
{
[self.tblView setSeparatorInset:UIEdgeInsetsZero];
}
// write in view did load
tableForBrands.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
None of suggested answers were suitable for my similar problem. Implementing this method in tableView delegate finally worked:
- (void)tableView:(UITableView *)tableView
willDisplayCell:(UITableViewCell *)cell
forRowAtIndexPath:(NSIndexPath *)indexPath
{
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
}
If you are using Storyboards you can just drag and drop an UIView into your UITableView below your cells and set its height to 0. (Have only tested in an iOS 8 project)
I guess this is what you are looking for.
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
return 1.0f;
}
You can set the table view to be grouped instead of plain - this changes the look a bit but at least removes the extra lines.
I had this exact problem and ended up changing to grouped views. Looks a lot better.
Some of previous suggestions contain a BIG conceptual error:
if You do:
[cell addSubview: ....
even time a cell is "reused", you will add a new subview for the divider!
avoid it in two ways:
a) use a TAG, and:
1) ask for a subview for that tag
let divider = cell.viewWithTag(TAG) ...
2) if present, do NOT add another subview
3) if NOT present add AND tag it.
b) create a custom view and ADD your custom divider in "init" "awakeFromNib" of custom cell.
code for a):
if let divider = cell.viewWithTag(DIVIDER_TAG) as? UIView{
// nothing.. eventually change color bases in IndexPath...
}else{
let frame = CGRectMake(0, cell.frame.height-1, cell.frame.width, 1)
divider.tag = DIVIDER_TAG
divider.backgroundColor = UIColor.redColor()
cell.addSubview(divider)
}
Swift Solution:
tableView.tableFooterView = UIView(frame: CGRectZero)
Worked on Xcode 7.2
Inside the cellForRowAtIndexPath
let separatorLineView:UIView = UIView(frame: CGRectMake(0,0,self.tableview.bounds.width,0.5))
separatorLineView.backgroundColor = tableView.separatorColor
cell!.contentView.addSubview(separatorLineView)

How to change custom viewForHeaderInSection width after rotation

I have to build a custom tableViewHeader in which at least two labels should be displayed, viz. a projectName and projectDescription. The contents of these two labels vary (i.e. in terms of string-length).
I managed to get a working version for the default device orientation (portrait) but if the user rotates the device to landscape the width of my custom headerView is not adjusted, and the user will see unused white space to the right.
The following code fragment is being used:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 50.0f;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
CGFloat wd = tableView.bounds.size.width;
CGFloat ht = tableView.bounds.size.height;
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0., 0., wd, ht)];
headerView.contentMode = UIViewContentModeScaleToFill;
// Add project name/description as labels to the headerView.
UILabel *projName = [[UILabel alloc] initWithFrame:CGRectMake(5., 5., wd, 20)];
UILabel *projDesc = [[UILabel alloc] initWithFrame:CGRectMake(5., 25., wd, 20)];
projName.text = #"Project: this project is about an interesting ..";
projDesc.text = #"Description: a very long description should be more readable when your device is in landscape mode!";
[headerView addSubview:projName];
[headerView addSubview:projDesc];
return headerView;
}
I noticed that the tableView:viewForHeaderInSection: will only be called once after viewDidLoad, but not after a device orientation change.
Should I implement the willRotateToInterfaceOrientation: method with something like:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
{
[self.tableView reloadSections:nil withRowAnimation:UITableViewRowAnimationNone];
}
I cannot figure out how to get the reloadSections: to work, forcing a recalculation of my customView.
If you use autoresizingMask the header adjusts correctly on rotation. No need to override anything else. I would set the automasks at the end of the code just before returning the view:
[headerView addSubview:projName];
[headerView addSubview:projDesc];
projName.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;
projDesc.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
headerView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
return headerView;

Calling a UITableViewDelegate method from ViewController

I'd like to call the following method from my view controller class:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
However for the life of me I can't figure out how to do it. I tried:
UIView *view = [tableView viewForHeaderInSection:section];
UIView *view = [self viewForHeaderInSection:section];
UIView *view = [self tableView:viewForHeaderInSection:section];
All give me errors. It's that extra tableView: bit on the beginning. Can anyone give some advice or at least explain what that tableView:(UITableView *)tableView means?
Thanks!
Steve
I don't know why you would want to call it, but if it is implemented in the same object that you're calling it from then you can use self:
UIView* view = [self tableView:tableView viewForHeaderInSection:section];
otherwise, you can get the delegate from the tableView and call the delegate:
id<UITableViewDelegate> theDelegate = tableView.delegate;
UIView* view = [theDelegate tableView:tableView viewForHeaderInSection:section];
Why would you want to call it? This is one of the UITableViewDelegate methods that are normally called automatically when the table is being constructed by the tableView. The tableView class object fills in the parameters that it needs when it makes the call to this method. The view controller only needs to provide the right delegate methods, customized by you, so it can set it up properly.
Did you customize the code, as in this example, in your delegate class?
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
// create the parent view that will hold header Label
UIView* customView = [[UIView alloc] initWithFrame:CGRectMake(10.0, 0.0, 300.0, 44.0)];
// create the button object
UILabel * headerLabel = [[UILabel alloc] initWithFrame:CGRectZero];
headerLabel.backgroundColor = [UIColor clearColor];
headerLabel.opaque = NO;
headerLabel.textColor = [UIColor blackColor];
headerLabel.highlightedTextColor = [UIColor whiteColor];
headerLabel.font = [UIFont boldSystemFontOfSize:20];
headerLabel.frame = CGRectMake(10.0, 0.0, 300.0, 44.0);
// If you want to align the header text as centered
// headerLabel.frame = CGRectMake(150.0, 0.0, 300.0, 44.0);
headerLabel.text = <Put here whatever you want to display> // i.e. array element
[customView addSubview:headerLabel];
return customView;
}
I'm not near my Mac, or I would give you one of my own examples. But this is the general way this method is used.
By the way, you can see that the parameter tableView is not referenced in the sample code above. If you really want to call this method, use nil. UITableViewDelegate protocol allows the controller to be delegate for more than one tableView. If this happens, the method should test to see which tableView is reference, so that specialized behavior can be accommodated for each tableView.
Additional info:
If you just want to see what the height of your tableView's header is, you can evaluate its sectionHeaderHeight property. There are other properties like this, such as sectionFooterHeight and rowHeight.
You should know that delegate methods are there to help the tableView, using your customization. So the delegate method tableView:heightForHeaderInSection: is actually for you to customize the header height. Your delegate methods tells the tableView what the height is. It isn't a way to examine a property of the tableView.
Apples documentation says that if you customize by using tableView:heightForHeaderInSection: then the tableView sectionHeaderHeight is not valid. You would expect this, because that property refers to the height of all of the section headers.
Using the sectionHeaderHeight property, which you can write to in this case, you can set all of the headers to the same height.
Here is some sample code from something I'm working on now. I've added an NSLog statement for you.
resultsTableVC = [[[ResultsTableVC alloc] initWithController:self] retain];
self.tableView = [[[UITableView alloc] initWithFrame:CGRectMake(0, 110, self.view.frame.size.width, self.view.frame.size.height-120) style:UITableViewStyleGrouped] retain];
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
self.tableView.autoresizesSubviews = YES;
self.tableView.layer.cornerRadius = 10.0f;
self.tableView.delegate = resultsTableVC;
self.tableView.dataSource = resultsTableVC;
self.tableView.backgroundView = nil;
self.tableView.backgroundColor = [UIColor clearColor];
self.tableView.separatorColor = [UIColor defaultResultTableBackgroundColor];
self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
[self.view addSubview:self.tableView];
NSLog(#"header: %f, row: %f", tableView.sectionHeaderHeight, tableView.rowHeight);
(Someone will probably point out that I don't need some of those retains. I'm still working on that.)
This tells me that the standard section height is 100 and the standard row height is 44.0. I have a pointer to my tableView, a property that I can use through this class.
Now if you are setting the header height using tableView:heightForHeaderInSection: then you should have the height already calculated in your program. I don't think you can query for the height of a particular section (or row) once you set it.
Does this help?

Can I force a UITableView to hide the separator between empty cells? [duplicate]

This question already has answers here:
Eliminate extra separators below UITableView
(34 answers)
Closed 6 years ago.
When using a plain-style UITableView with a large enough number of cells that the UITableView cannot display them all without scrolling, no separators appear in the empty space below the cells. If I have only a few cells the empty space below them includes separators.
Is there a way that I can force a UITableView to remove the separators in the empty space? If not I'll have to load a custom background with a separator drawn in for each cell which will make it harder to inherit behavior.
I found a somewhat similar question here, but I can't use a grouped UITableView in my implementation.
For iOS 7.* and iOS 6.1
The easiest method is to set the tableFooterView property:
- (void)viewDidLoad
{
[super viewDidLoad];
// This will remove extra separators from tableview
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
}
For previous versions
You could add this to your TableViewController (this will work for any number of sections):
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
// This will create a "invisible" footer
return 0.01f;
}
and if it is not enough, add the following code too:
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
return [UIView new];
// If you are not using ARC:
// return [[UIView new] autorelease];
}
For Swift:
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableFooterView = UIView() // it's just 1 line, awesome!
}
You can achieve what you want by defining a footer for the tableview. See this answer for more details:Eliminate Extra separators below UITableView
Using the link from Daniel, I made an extension to make it more usable:
//UITableViewController+Ext.m
- (void)hideEmptySeparators
{
UIView *v = [[UIView alloc] initWithFrame:CGRectZero];
v.backgroundColor = [UIColor clearColor];
[self.tableView setTableFooterView:v];
[v release];
}
After some testings, I found out that the size can be 0 and it works as well. So it doesn't add some kind of margin at the end of the table. So thanks wkw for this hack. I decided to post that here since I don't like redirect.
Swift Version
The easiest method is to set the tableFooterView property:
override func viewDidLoad() {
super.viewDidLoad()
// This will remove extra separators from tableview
self.tableView.tableFooterView = UIView(frame: CGRectZero)
}
For Swift:
self.tableView.tableFooterView = UIView(frame: CGRectZero)
For newest Swift:
self.tableView.tableFooterView = UIView(frame: CGRect.zero)
If you use iOS 7 SDK, this is very simple.
Just add this line in your viewDidLoad method:
self.yourTableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
Setting the table's separatorStyle to UITableViewCellSeparatorStyleNone (in code or in IB) should do the trick.
I use the following:
UIView *view = [[UIView alloc] init];
myTableView.tableFooterView = view;
[view release];
Doing it in viewDidLoad. But you can set it anywhere.
The following worked very well for me for this problem:
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
CGRect frame = [self.view frame];
frame.size.height = frame.size.height - (kTableRowHeight * numberOfRowsInTable);
UIView *footerView = [[UIView alloc] initWithFrame:frame];
return footerView; }
Where kTableRowHeight is the height of my row cells and numberOfRowsInTable is the number of rows I had in the table.
Hope that helps,
Brenton.

Resources