This code creates a margin at the top and bottom of the UITableView. How can I modify it to do the same but between each individual UITableViewCell?
// set header height
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 10;
}
// set header colour
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *headerView = [[UIView alloc] init];
headerView.backgroundColor = [UIColor lightGrayColor];
return headerView;
}
// set footer height
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
return 10;
}
// set footer colour
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
UIView *headerView = [[UIView alloc] init];
headerView.backgroundColor = [UIColor lightGrayColor];
return headerView;
}
If successful, I'd also like to be able to add similar left and right margins if possible.
Use an extra Background UIView with top, left. bottom and right margin.[red background view in the picture]. Add all other subViews on this view.
Related
My app contains a UITableView which has section footers. When the user scrolls to the bottom of the tableView, sometimes a separator inset appears between the last cell and the tableFooter. This behaviour is inconsistent.
Is there a way to force this separator to always appear or never appear? Did any of you noticed this same inconsistent behaviour? Seems like a bug to me.
EDIT
I'm using
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
UILabel *footer = [[UILabel alloc] init];
footer.backgroundColor = [UIColor whiteColor];
footer.font = [footer.font fontWithSize:15];
footer.textAlignment = NSTextAlignmentCenter;
return footer;
}
but you could easily reproduce the same problem only using
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section;
To do this you'll have to override the standard UIView used as the footer.
You can do this by overriding the delegate method -(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section.
-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
UIView *myFooterView;
// create a view with a label and without a line at the top etc...
return myFooterView;
}
I am not sure why you are getting inconsistent results. Maybe try to add a background to your footer view. Here is my code:
-(UIView *) tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
UIView *footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 33)];
[footerView setBackgroundColor:[UIColor grayColor]];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, footerView.bounds.size.width, 20)];
label.text = #"Footer";
[label setTextAlignment:NSTextAlignmentCenter];
[footerView addSubview:label];
return footerView;
}
And here is the result:
This is a bit of a lazy way of doing it but it works none the less.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CellIdentifyer"];
if (indexPath.row == tableArray.count) {
cell.separatorStyle = UITableViewCellSeparatorStyleNone;
}
return cell;
}
here is the solution, very easy!
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CellIdentifyer"];
cell.separatorInset = (indexPath.row == totalNumber-1) ? UIEdgeInsetsMake(0, INT16_MAX, 0, 0) : UIEdgeInsetsZero;
return cell;
}
I found some workaround about it:
Whenever you expect this extra separator could appear (for example, when user scrolls to the bottom like you described) - add these lines of code:
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
The logic is something like that: first string of code removes bottom separator, and the second one doesn't add it. It worked for me in some cases, but it is not a 100% fix.
I guess, it might be an Apple bug also, as sometimes bottom separator disappears in their 'Reminders' app.
Normally my screen display is like this:
When I use this code
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, 30)];
[headerView setBackgroundColor:[UIColor whiteColor]];
return headerView;
}
my output is like this:
My section index text is not visible. I know that the section header view add my custom view. I want to change section header color and also display index text.
#Khawar answer i get this output
this is work 100% and you can change your index or header text color
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
{
view.tintColor = [UIColor blueColor];
// if you have index/header text in your tableview change your index text color
UITableViewHeaderFooterView *headerIndexText = (UITableViewHeaderFooterView *)view;
[headerIndexText.textLabel setTextColor:[UIColor blackColor]];
}
output:
Try to set the height for UITableView header.
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 30.0;
}
If you only need to change the background color of section header while displaying section title, you don't need to create custom view for that. Custom view would overwrite your default header and your title would not be shown, unless you add custom UILabel in your custom view. Just use following UITableView delegate to change background color.
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section {
view.tintColor = [UIColor redColor];
}
See results before and after.
----------------Before------------------
----------------After------------------
Hope this fixes the issue.
You have to give title for section... Or you can use this method..
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UILabel *headerView = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, 30)];
[headerView setBackgroundColor:[UIColor colorWithWhite:0 alpha:0.5]];
headerView.text = [self tableView:tableView titleForHeaderInSection:section];
return headerView;
}
I have a UITableView with a number of sections (not rows). I'd like to add the UIImageView as a separator between each sections at the center (except the last cell).
The space between cells is 30
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 30;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *headerView = [[UIView alloc] init];
headerView.backgroundColor = [UIColor clearColor];
return headerView;
}
The screenshot
I'd like to set the position like at the screenshot.
The code I've made
[self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
The cell height is 81.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Some code
UIImageView *separatorIView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 96, 196, 2)];
[separatorIView setImage:[UIImage imageNamed:#"grayline.png"]];
[cell.contentView addSubview:separatorIView];
return cell;
}
The grayline appears if I set the y coordinate < then cell height.
Thanks in advance.
The result
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 30;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *headerView = [[UIView alloc] init];
headerView.backgroundColor = [UIColor clearColor];
if (section > 0) {
UIImageView *img = [[UIImageView alloc] initWithFrame:CGRectMake(62, 14, 196, 2)];
[img setImage:[UIImage imageNamed:#"grayline.png"]];
[headerView addSubview:img];
}
return headerView;
}
Custom separator position is not possible because they are privately defined for its frame, apart from that if you need that kind of effect then you have to add a image in header like custom space and color with require view with that only you can get the desired view
As you are setting a head view height you can add separator in header. Table View has a delegate method named "viewForHeaderInSection".
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIImageView *img = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 5)];
[img setImage:[UIImage imageNamed:#"grayline.png"]];
return img;
}
If you set the separator image in this delegate method you don't need to do anything in cellForRowAtIndexPath.
Let me know if that helps... :)
Edit:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 5;
}
`
You can set Separator color using setSeparator color in which you can pass image
like,
[self.tableView setSeparatorColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"grayline.png"]]];
just try to make the height of the last header as zero and see if it works.
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if(make_cndition_for_lastsection)
return 0;
else
return 30;
}
UITableView showing separator even there is no rows. But when I use viewForFooterInSection the separator is gone. I want it to keep showing up. What should I do ?
Here is my code when I add footer in it :
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 3;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"s"];
cell.textLabel.text = [NSString stringWithFormat:#"%d", indexPath.row + 1];
cell.textLabel.textAlignment = NSTextAlignmentCenter;
return cell;
}
// -------------------------- footer code start here --------------------------
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 40;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.backgroundColor = [UIColor grayColor];
UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 40)];
title.text = #"footer here";
title.textAlignment = NSTextAlignmentCenter;
title.textColor = [UIColor whiteColor];
[view addSubview:title];
return view;
}
this github project may give you some advices:
CLTableWithFooterViewController
Of course need some change if you would like the footer always display on the screen even if with a lot of cells.
remove - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
and - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
use this code to keep the footer down (but always visible) and keep the separator:
#implementation tableView {
__weak UIView *_staticView;
}
- (void)viewDidLoad {
UIView *staticView = [[UIView alloc] initWithFrame:CGRectMake(0, self.tableView.bounds.size.height-50, self.tableView.bounds.size.width, 50)];
staticView.backgroundColor = [UIColor redColor];
//add other code for UILabel here
[self.tableView addSubview:staticView];
_staticView = staticView;
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 50, 0);
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
_staticView.transform = CGAffineTransformMakeTranslation(0, scrollView.contentOffset.y);
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
// this is needed to prevent cells from being displayed above our static view
[self.tableView bringSubviewToFront:_staticView];
}
I guess you just have a single section,right? Before you using viewForFooterInSection,it just fills blank cells all the way down.But when you call viewForFooterInSection,tableview will put a footer at the end of the section.Since you don't have the second section,it stops draw any cells.So you can make a blank second section,it will fill blank cells to the second section.
So my UITableView has a header, which is the UIImageView shown, and comments below the image. I am trying to increase the space between the image and the comments table.
(I have tried increasing the height of the header, but it doesn't work in my case because it will result in a bigger UIImageView and the image won't cover the view completely)
I experimented with this hack:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CommentsTableCell";
CommentsCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
Comment *comment = [self.comments objectAtIndex:indexPath.row];
[cell setUsername:comment.handle andText:comment.text];
/* Dirty hack:
1. We cannot increase the height of the header because that will leave spaces in the image.
2. The only way we can increase the margin from the comments table to the picture is by
increasing the individual inset of the first and last comments cell
*/
if (indexPath.row == 0) {
[cell setContentInset:UIEdgeInsetsMake(COMMENTS_PADDING * 10 , 0, 0, 0)];
} else if (indexPath.row == [self.comments count] - 1) {
[cell setContentInset:UIEdgeInsetsMake(0, 0, COMMENTS_PADDING * 10 , 0)];
}
return cell;
}
and in my CommentsCell.m:
- (void)awakeFromNib {
self.commentText.scrollEnabled = false;
self.commentText.editable = false;
self.commentText.contentInset = UIEdgeInsetsMake(-1 * COMMENTS_PADDING, 0, 0, 0);
}
- (void)setUsername:(NSString *)username andText:(NSString *)text {
[self.commentText setAttributedText:[CommentsCell getContentStringForUsername:username andText:text]];
}
- (void)setContentInset:(UIEdgeInsets)inset {
self.commentText.contentInset = inset;
}
but the first comment still has the same inset. I checked the debugger and awakeFromNib is occurring before cellForRowAtIndexPath. Do you see why my method is not working?
I am also open to other suggestions.
You should be able to add some space to the header view just below the image you display. Instead of setting the table's header view to a UIImageView, why not create a container view that you can add the image view to and then just have some space below it.
- (UIView *) buildTableHeaderView {
UIImage *image = [UIImage imageNamed: #"my_image.png"];
CGFloat height = image.size.height + 20;
UIImageView *imageView = [[UIImageView alloc] initWithFrame: CGRectMake(0, 0, self.myTableView.frame.size.width, height)];
[imageView setImage: image];
UIView *headerView = [[UIView alloc] initWithFrame: CGRectMake(0, 0, self.myTableView.bounds.size.width, height)];
[headerView addSubview: imageView];
return headerView;
}
What you can do is create a custom UIView (with .xib if you want for easier UI design) with a space on the bottom and return it from - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section method of the UITableViewDelegate, also don't forget to return the height for the header view by implementing the - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section method of the same UITableViewDelegate.
Here is a short example:
-UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
YourCustomHeaderView *headerView = [YourCustomHeaderView instantiateView]; //static method (you can rename it) that will load the custom view from a .xib
//do aditional UI setup or not
return headerView;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return DEFAULT_HEADER_HEIGHT; //a defined value
}
If you are having a single header view, then you should use the same custom header view creation/init/setup, but move your table downwards in is superview and add the custom header view at the top at any position you like.