Determine custom section header frame when tableView mode grouped - ios

I provide a custom section header via the tableView's delegate method. It works fine in plane mode but I can't figure out the correct margin in grouped style.
Does anyone know how to make the section header aligned with the tableView cells?

You can create a custom label and adjust its frame accordingly.
For eg.
- (UIView *)tableView:(UITableView *)aTableView viewForHeaderInSection:(NSInteger)section
{
UIView *view=[[UIView alloc] initWithFrame:aTableView.tableHeaderView.frame];
UILabel *label=[[UILabel alloc] initWithFrame: CGRectMake(//set frame of the label as you want)];
[label setFont:[UIFont fontWithName: size:]];
[label setTextColor:[UIColor blackColor]];
[label setShadowOffset:CGSizeMake(0.0f, 1.0f)];
[label setShadowColor:[UIColor redColor];
label.backgroundColor=[UIColor clearColor];
if(section==0)
{
[label setText://set your section0 title];
}
else if(section ==1)
{
[label setText://set your section1 title];
}
[view addSubview:label];
[label release];
return [view autorelease];
}
Hope this helps :)

Not tested in every flavor but a good starting point.
In
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
pass the tableView.style parameter to your own method providing the header.
Create a view a frame like
CGRect(0,0,CGRectGetWidth(tableView.frame), CGRectGetHeight(tableView.frame)
but add a subview with a frame
CGRectInset(frame, 30,0)
if you have a grouped tableView style. Set a the autoresizingMask to flexible width and it works.
Slightly modified in a way that I had to give an additional parameter to the creation method for the SectionHeaderView as the margin is different for presentationStyle FullScreen and Formsheet.
CGFloat margin = 0;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
margin = style == UITableViewStyleGrouped ? modalStyle == UIModalPresentationFormSheet ? 28 : 38 : 0;
}
else {
margin = style == UITableViewStyleGrouped ? 5 : 0;
}
UIView *view = [[UIView alloc] initWithFrame:CGRectInset(frame, margin, 0)];
view.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[self addSubview:view];

Related

Set position of the header at the beginning of the TableView

I have to set my headerView at the beginning of the table View.
It seems to be fixed please help.
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
UIView *headerView = [[[UIView alloc] initWithFrame:CGRectMake(0,0,tableView.frame.size.width,40)] autorelease];
headerView.backgroundColor = [Utility consumerLightColor];
UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(5, 0, 250, headerView.frame.size.height)];
headerLabel.text = #"Upcoming Appointments";
headerLabel.textAlignment = NSTextAlignmentLeft;
headerLabel.textColor = [UIColor whiteColor];
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) {
headerLabel.font = [UIFont fontWithName:#"bauhaus md bt" size:15.0f];
}
else{
headerLabel.font = [UIFont fontWithName:#"bauhaus md bt" size:16.0f];
}
// // NSLog(#"title --> %#",[locationArray objectAtIndex:i]);
headerLabel.backgroundColor = [UIColor clearColor];
[headerView addSubview:headerLabel];
[headerLabel release];
return headerView;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
if (tableView == appointmentListtableView) {
CGFloat changeheight = 40.00;
return changeheight;
}
else{
return 0.0f;
}
}
All I want is to set the position of the header view (Upcoming Appointments)at the beginning of the table View and it should not be fixed.
Maybe you need to remove table header , not section header ?
To do this you need to set:
tableView.tableHeaderView = nil
See keep always in mind,
If you want to set Static header to table view then its good & best practice to set it as a ,
yourTableView.tableHeader = yourHeaderView;
If your headers are dynamic you don't know weather how much sections want to set, then go with method,
viewForHeaderInSection:tableView
That doesn't mean you can use only one at a time not at all, You can use both at a time also,
Now comes to your case, i think you are doing something wrong in the tableViewHader, set it to nil if you don't need anymore,
But i am curious about one thing even if you have set tableViewHeader still why does it show upper & lower side of your secion header,You are setting tableViewHeader or sectionFooter or showing the UITableViewCell

UITableViewCell scroll over custom UITableView header title

I have a simple UITableViewController which contains about 40 UITableViewCells and the UITableViewController is embedded in a UITabBarController. The UITableViewController is created in Storyboard.
I am overriding the custom UITableViewHeader Text so that I can have a few guides there for users. I am noticing some really weird behaviour with this as represented by the following images:
As can be seen, the UITableView scrolls, but the header text remains there and it looks terrible.
Here is how I'm setting up the custom header:
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
// Custom label for the section header titles
UILabel *label=[[UILabel alloc]initWithFrame:CGRectMake(25, 0, tableView.frame.size.width, 110)];
label.textAlignment = NSTextAlignmentCenter;
label.textColor = [UIColor whiteColor];
label.numberOfLines = 0;
[label setFont:[UIFont systemFontOfSize:17.0]];
if (section == 0)
{
label.text = #" Add to this by marking a leaflet or video as a favourite.\n\nYou can do this by swiping left on any leaflet or video cell.";
}
return label;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
CGFloat headerHeight = 0;
headerHeight = 110;
return headerHeight;
}
I have worked with different sizes, but no matter what I do, it still behaves in the same way.
If anyone has any thoughts or guidance on this, that would really be appreciated. I just want the header text to also scroll up with the table view and to therefore be hidden from view when scrolling.
You can add your header as the tableHeaderView like this:
- (void)viewDidLoad {
[super viewDidLoad];
UILabel *label=[[UILabel alloc]initWithFrame:CGRectMake(25, 0, self.tableView.frame.size.width, 110)];
label.textAlignment = NSTextAlignmentCenter;
label.textColor = [UIColor blackColor];
label.numberOfLines = 0;
[label setFont:[UIFont systemFontOfSize:17.0]];
label.text = #" Add to this by marking a leaflet or video as a favourite.\n\nYou can do this by swiping left on any leaflet or video cell.";
self.tableView.tableHeaderView = label;
}
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
// Custom label for the section header titles
UIView *view=[[UIView alloc]initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 110)];
UILabel *label=[[UILabel alloc]initWithFrame:CGRectMake(25, 0, tableView.frame.size.width, 110)];
label.textAlignment = NSTextAlignmentCenter;
label.textColor = [UIColor whiteColor];
label.numberOfLines = 0;
[label setFont:[UIFont systemFontOfSize:17.0]];
if (section == 0) {
label.text = #" Add to this by marking a leaflet or video as a favourite.\n\nYou can do this by swiping left on any leaflet or video cell.";
}
[view addSubView:label];
[view setBackgroundColor:[UIColor blueColor]]; // the color for background
return view;}

UITableView modify only one header section after delegate methods

I'm creating a UITableView with more section "closed". When I tap on a section, with a workaround, I make the section explode showing the rows for that section. The problem that I have is that I have to animate the header to collapse it to an half of its width.
This is the code I'm using
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
Sport *sport = [self.sportList objectAtIndex:section];
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, tableView.frame.size.width, SECTION_HEIGHT)];
headerView.backgroundColor = [UIColor colorWithRed:31.0/255.0 green:59.0/255.0 blue:143.0/255.0 alpha:1.0];
UILabel *sportTitle = [[UILabel alloc] initWithFrame:CGRectMake(10.0, 2.0, tableView.frame.size.width, SECTION_HEIGHT-4)];
sportTitle.textColor = [UIColor whiteColor];
[headerView addSubview:sportTitle];
UIButton *sportButton = [[UIButton alloc] initWithFrame:headerView.frame];
[sportButton addTarget:self action:#selector(didSelectedButton:) forControlEvents:UIControlEventTouchUpInside];
[sportButton setTitle:#"" forState:UIControlStateNormal];
[sportButton setBackgroundColor:[UIColor clearColor]];
sportButton.tag = section;
[headerView addSubview:sportButton];
return headerView;
}
This is the selector:
-(void)didSelectedButton:(UIButton *)_button
{
if (self.delegate && [self.delegate respondsToSelector:#selector(didSelectedSport:)])
{
[self.delegate didSelectedSport:sport];
}
}
The delegate updates only the dataSource and calls the reloadData, making possible the explosion/collapse of the sections. But now I want to animate the changes to the width of the header for that section, is it possible? Thanks
EDIT: I can modify the header using the property superview of the UIButton in the selector, but I have to do it after the controller drew it
Try using the function below. Set your superview of uibutton as the from view in the method.
Create another view with your needed width and set it as to view in the method. Give a animation of choice in options.
[UIView transitionFromView:from
toView:to
duration:.5
options:UIViewAnimationOptionTransitionFlipFromBottom
completion:^(BOOL finished) {
}];

unwanted white space "under" tableView subview when tableView scrolled to its content limits

I have a UITableViewCell as a subview in a custom view controller. It works great except that when it scrolls to its top or bottom of its contentSize limit, it "keeps going" and leaves some white space exposed behind it. This is particularly irritating because I do have a UIView covering the entire screen behind the tableView, and that view is set to a non-white color. I also added a subview exactly underlaying the tableview with the same background color, again attempting to block the white. I also set the UIApplication Window background color to a non white color. None of this worked.
I would have thought that even if my TableView bounces around its origin frame, the "exposed" view should match the underlying view rather than be white. How can I fix my tableView so that it retains all its scroll properties but doesn't reveal white when it bounces around at the end of a scroll?
Here is a screen shot of the effect. The white appears the tableViewHeader and below a UISCrollView that occupies the top of the screen. This appears when I scroll the tableView all the way to one extreme. The white space appears at the bottom rather than the top of the tableView if I scroll all the way to the other end.
Here's the relevant code, quite vanilla I think:
#interface JudgeViewController () <UITextFieldDelegate, UITextViewDelegate, UINavigationControllerDelegate, UIGestureRecognizerDelegate, UITableViewDataSource, UITableViewDelegate, UIViewControllerRestoration, UIScrollViewDelegate>
#property (nonatomic) UITableView *tableView;
#end
functions to set tableViewCells
#pragma mark - tableview appearance and actions
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
StatsViewController *svc = [[StatsViewController alloc] init];
svc.user = self.object.answerUser[indexPath.row];
svc.fromJudge = YES;
[self.navigationController pushViewController:svc animated:YES];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.object.answerArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
UILabel *label = nil;
cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if(cell ==nil)
{
cell = [[UITableViewCell alloc] initWithFrame:CGRectZero];
label = [[UILabel alloc] initWithFrame:CGRectZero];
[label setLineBreakMode: UILineBreakModeWordWrap];
[label setMinimumFontSize:SMALL_FONT_SIZE];
[label setNumberOfLines:0];
[label setFont:[UIFont systemFontOfSize:SMALL_FONT_SIZE]];
[label setTag:1];
// [[label layer] setBorderWidth:2.0f];
[[cell contentView] addSubview:label];
}
CGFloat width = [[UIScreen mainScreen] bounds].size.width;
CGFloat height = [[UIScreen mainScreen] bounds].size.height;
NSString *text = self.object.answerArray[indexPath.row];
CGSize constraint = CGSizeMake(.8*CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN)*2, 200000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:SMALL_FONT_SIZE] constrainedToSize:constraint];
if(!label)
label = (UILabel *)[cell viewWithTag:1];
[label setText:text];
[label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, .8*CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN)*2, MAX(size.height, 44.0f))];
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button1.frame = CGRectMake(.85*width, label.frame.size.height/2-2*CELL_CONTENT_MARGIN, .12*width, 20);
[button1 setTitle:#"UP" forState:UIControlStateNormal];
button1.titleLabel.font =[UIFont systemFontOfSize:SMALLEST_FONT_SIZE];
[button1 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button1 addTarget:self action:#selector(upVoteA:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:button1];
[cell.contentView bringSubviewToFront:button1];
UIButton *button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button2.frame = CGRectMake(.85*width, label.frame.size.height/2+2*CELL_CONTENT_MARGIN, .12*width, 20);
[button2 setTitle:#"DOWN" forState:UIControlStateNormal];
button2.titleLabel.font =[UIFont systemFontOfSize:SMALLEST_FONT_SIZE];
[button2 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button2 addTarget:self action:#selector(downVoteA:) forControlEvents:UIControlEventTouchUpInside];
CGFloat moduloResult = indexPath.row % 2;
if(moduloResult>0)
{
cell.backgroundColor = [UIColor colorWithRed:1 green:0.647 blue:0 alpha:.6];
}
else
{
cell.backgroundColor = [UIColor colorWithRed:1 green:0.647 blue:0 alpha:.4];
}
cell.opaque = NO;
cell.alpha = 0.2;
[cell.contentView addSubview:button2];
[cell.contentView bringSubviewToFront:button2];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
-(void)keyboardToJudge
{
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row < [self.object.answerArray count])
{
NSString *text = self.object.answerArray[indexPath.row];
CGSize constraint = CGSizeMake(.8*CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN)*2, 200000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE-2.0f] constrainedToSize:constraint];
CGFloat height = MAX(size.height, 44.0f);
return height + (CELL_CONTENT_MARGIN)*2;
}
else
{
return 200.0f;
}
}
functions setting out layout:
-(void)viewDidLoad
{
...among other things setting up top scroll view (top part of view with gray background and orange text)...
if(self.navigationController.navigationBar.frame.size.height>0)
{
self.scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 5, width, height*SCROLL_VIEW_OFFSET)];
}
else
{
self.scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, statusBarHeight+5, width, height*SCROLL_VIEW_OFFSET)];
}
self.scroll.backgroundColor = BACKGROUND_COLOR;
self.scroll.contentSize =CGSizeMake(width, .5*height);
self.scroll.delegate = self;
self.scroll.contentInset = UIEdgeInsetsMake(30, 0, 30, 0);
[self.scroll setShowsHorizontalScrollIndicator:NO];
...adding buttons to self.scroll...
[self.view addSubview:self.scroll];
....
self.tableView = [[UITableView alloc] initWithFrame:frame];
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, _width, _height*.1)];
self.tableView.tableFooterView.backgroundColor = BACKGROUND_COLOR;
self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, _width, _height*.1)];
self.tableView.tableHeaderView.backgroundColor = BACKGROUND_COLOR;
....tableView hidden state is changed to yes in another function if row count is zero but not usually...
self.tableView.hidden = NO;
[self.view addSubview:self.tableView];
...
}
Finally, I also call :
[self.tableView reloadData];
after reloading data from a webserver and depending on the results either set the tableView to hidden or not (not hidden if there are results to display). That should be every line of code that touches the tableView subview.
Add to your viewDidLoad
[self.tableView setBackgroundColor:BACKGROUND_COLOR];
Set the background color of your tableView and you'll be fine
Change this line:
self.scroll.contentInset = UIEdgeInsetsMake(30, 0, 30, 0);
To this:
self.scroll.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
You are adding a footer to your tableview with that line. The following image is from the IOS dev Library
Set the table view estimate to 0 (Uncheck Automatic) in the size inspector

How to center UITableView Section Footer with Support for Orientation?

EDIT:
After messing with this for days the real questions I have are the following:
1. Does UITableView take up the entire view?
2. If so, how does it set the bounds of the cells to that it looks like it only takes up part of the view.
3. How do I get the bounds of the cells - or more accurately how do I know the bounds of the visible area that the cells are taking up. self.tableView.bounds.size.width does not help because it returns the width of the view.
Thanks.
Leaving the previous info below in case it helps make my question clearer.
Can this be possible?
I have read the apple docs and trolled the forums here and elsewhere and can't find and answer to this.
Does the footer in a UITableVIew actually take up the entire view no matter what you do? Does it not have a concept of the table width?
Example:
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
UIView *footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
[footerView setBackgroundColor:[UIColor redColor]];
return footerView;
}
This code will create a red line from one edge to the other. No matter what boundaries you give it the line will take up the entire view. The problem with this is that if you want to center a label in that footer you don't have any way to know where center is if you are supporting orientation changes.
For instance in an iPad app I am trying to do the following:
if ([footerText length] > 0) {
UIView *customView = [[[UIView alloc]initWithFrame:CGRectMake(0.0, 0.0, 0, 0.0)] autorelease];
[customView setBackgroundColor:[UIColor grayColor]];
UILabel *footerLabel = [[UILabel alloc] initWithFrame:CGRectZero];
footerLabel.numberOfLines = 2;
footerLabel.adjustsFontSizeToFitWidth = NO;
[footerLabel setTextAlignment:UITextAlignmentCenter];
[footerLabel setBackgroundColor:[UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.5]];
[footerLabel setOpaque:NO];
[footerLabel setTextColor:[UIColor whiteColor]];
[footerLabel setShadowColor:[UIColor lightGrayColor]];
[footerLabel setFont:[UIFont boldSystemFontOfSize:14]];
[footerLabel setFrame:CGRectMake(customView.center.x/0.3, 0.0, 600, 40.0)];
[footerLabel setText:footerText];
[customView addSubview:footerLabel];
[footerLabel release];
NSLog(#"customView width = %f", customView.frame.size.width);
NSLog(#"tableview width = %f", self.tableView.frame.size.width);
NSLog(#"tableview center = %f", self.tableView.center.x);
return customView;
} else {
return nil;
}
The table's center in portrait should be 384 (it's in the detail view/right side) and 351.5 in landscape. But when I use setCenter or try to adjust the left edge based on that center it does not center up.
Final question: How does one center a custom view in a footer with support for orientation when the footer seems to have no concept of the table bounds? I must be missing something in the docs because this has to be a problem solved by someone else but I can't find it.
Thanks for your time.
To center something within the tableview, you need to wrap it in a container, and set the appropriate autoresize mask for both the embedded view and the container.
The container should be flexible width, and the embedded view should have both flexible side margins.
eg:
- (UIView *) tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
static UIView *footerView;
if (footerView != nil)
return footerView;
NSString *footerText = NSLocalizedString(#"Some Display Text Key", nil);
// set the container width to a known value so that we can center a label in it
// it will get resized by the tableview since we set autoresizeflags
float footerWidth = 150.0f;
float padding = 10.0f; // an arbitrary amount to center the label in the container
footerView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, footerWidth, 44.0f)];
footerView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
// create the label centered in the container, then set the appropriate autoresize mask
UILabel *footerLabel = [[[UILabel alloc] initWithFrame:CGRectMake(padding, 0, footerWidth - 2.0f * padding, 44.0f)] autorelease];
footerLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
footerLabel.textAlignment = UITextAlignmentCenter;
footerLabel.text = footerText;
[footerView addSubview:footerLabel];
return footerView;
}

Resources