Basically, I have a UITableView which will hold, say, alarms.
There is a '+' button at the bottom of the screen to add alarms but, of course, before any alarms are added the table is blank.
If there are no alarms, and the table view is empty, I'd like there to be some sort of placeholder text like "press the + to add an alarm".
I've tried this and also found a suggestion about making a placeholder UITableView with a cell that shows the above text. Then you show/hide the placeholder UITableView or the alarm UITableView depending on whether or not there are any alarms. I couldn't get that to work and think it's a bit much for wanting a simple string to show up.
I also tried creating a placeholder UITableViewCell if there are no alarms but that messes with numberOfRowsInSection which, in turn, breaks the ability to delete cells, as well it should (because numberOfRowsInSection can never be zero).
UPDATE: I also tried adding a UILabel to the tableView's tableHeaderView (and tableFooterView). No luck.
Any ideas?
After some researching on this site, I solved it by implementing the following delegate callbacks:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
if (self.alarmList.count == 0) {
UILabel *label = [[UILabel alloc] init];
label.text = #"press the + to add an alarm";
label.textAlignment = UITextAlignmentCenter;
label.numberOfLines = 2;
label.font = [UIFont boldSystemFontOfSize:16];
label.backgroundColor = [UIColor darkTextColor];
label.textColor = [UIColor whiteColor];
return label;
} else {
return nil;
}
}
- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
if (self.alarmList.count == 0) {
return 68;
} else {
return 0;
}
}
Related
I have added footerview programmatically for each section as follows. I could able to see the footerview.
However, when I scroll up or down at the bottom or at the top of the tableview, footerview overlays on top of tableviewcells.
How could I able to disable it?
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
if(adminOrderElements[section].expanded && [adminOrderElements[section].notes length]>0)
{
return 60;
} else {
return 0;
}
return 60;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
UIView *footer = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 60)];
footer.backgroundColor = [UIColor clearColor];
UILabel *lbl = [[UILabel alloc]initWithFrame:footer.frame];
lbl.backgroundColor = [UIColor clearColor];
lbl.text = #"Your Text";
lbl.textAlignment = NSTextAlignmentCenter;
[footer addSubview:lbl];
return footer;
}
Before Scroll
After Scroll
If I understand your question correctly, you only have to change the UITableViewStyle to UITableViewStyleGrouped. According to the docs, for table views using grouped style the section headers and footers do not float.
I got a table view with two sections, no crazy code, just my delegate methods.
It works pretty fine, like i want it to work. It should just look like on this screenshot:
Now the problem is: Sometimes while scrolling or flicking the scoll view to the bounds, this happens (if you can't see it: There is 1 or 1/2 pixel in gray on the top of the second section header, what is not intended to be so):
So, is this a iOS 7.1 or 7.x bug? I'm not using a custom view for the header. Does anyone know how to fix this?
Feedback really is appreciated.
I had this same problem that I battled for a few weeks, and the way I solved it was to set the tableView's separatorStyle to UITableViewCellSeparatorStyleNone, and add a custom subview that is a line to the cell's contentView.
Then in your cellForRowAtIndexPath method, hide the line subview of the last cell in the section:
- (UIView *)lineView
{
// Your frame will vary.
UIView *colorLineView = [[UIView alloc]initWithFrame:CGRectMake(82, 67.5, 238, 0.5)];
colorLineView.backgroundColor = [UIColor blackColor];
return colorLineView;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
static NSString *identifier = #"cellIdentifier";
UIView *lineView = [self lineView];
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
if (cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
cell.selectionStyle = UITableViewCellSelectionStyleDefault;
[cell.contentView addSubview:lineView];
}
if (indexPath.section == 0)
{
if (indexPath.row == keys.count -1)
{
lineView.hidden = YES;
}
}
return cell;
}
It may be recycling one of the cell views with the separator from the scroll. This is a long shot, but what if you were to try tweaking the footer view for the section by returning an empty view?
-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
return [[UIView alloc] init];
}
It's also a good trick for removing empty cells from the table when you have only a couple rows.
I tried it with multiple different things and the cleanest approach i found is this.
I created a custom view for the header, but wanted it to look the same as the original not modified header:
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 34)];
[headerView setBackgroundColor:[UIColor groupTableViewBackgroundColor]];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(15, 0, tableView.frame.size.width, 34)];
[label setFont:[UIFont boldSystemFontOfSize:14]];
if (section == 0) {
NSMutableArray *difficultyArray = [dictionary objectForKey:#"Difficulty"];
NSString *difficulty = [difficultyArray objectAtIndex:0];
[label setText:[NSString stringWithFormat:#"Time Challenge (%#)", difficulty]];
} else {
[label setText:#"Freeplay (5x5 board)"];
}
[headerView addSubview:label];
return headerView;
}
Now we got the sections as they would appear without custom header views, but the bug still exists. I made it simple and clean:
UIView *lineFix = [[UIView alloc] initWithFrame:CGRectMake(0, 77.5, self.tableView.frame.size.width, 0.5)];
lineFix.backgroundColor = [UIColor groupTableViewBackgroundColor];
[self.tableView addSubview:lineFix];
Now we set a view over the buggy seperator with a height of 0.5 pixel, the seperator isn't visible anymore. Between the two section headers now is a 0.5 height view what shouldn't be there, but since i set it the same color as the section background color it isn't noticeable. The view moves, because it is a subview of the tableview, the same direction like the tableview.
If you have questions, just add a comment.
I'm using a UITableView with 2 sections and i preserve a specific width for each section header as follows:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
if (section==0) {
return 45;
}
if (section==1) {
return 20;
}
return 0;
}
also here's viewForHeaderInSection delegate method
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UILabel *lbl = [[UILabel alloc] init];
lbl.textAlignment = NSTextAlignmentCenter;
lbl.font = [UIFont fontWithName:#"AmericanTypewriter-Bold" size:15];
lbl.textColor = [UIColor orangeColor];
lbl.shadowOffset = CGSizeMake(0,1);
lbl.alpha = 0.9;
lbl.textAlignment = NSTextAlignmentLeft;
if(section == 0){
lbl.text =[LocalizationSystem get:#"Share_Today_times" alter:#""];
}
if(section == 1){
lbl.text =[LocalizationSystem get:#"Share_Month_Times" alter:#""];
}
return lbl;
}
the problem is that there's a space between the first section and its header which doesn't exist in the other sections, as you see in the image below the second section has no space between its header which appears apparently in the first section (the region with the black dots), does any one know how to solve these issue? thanks in advance
Did you try changing your heightForHeaderInSection method's implementation to
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
return 20;
}
The reason might be that Share Today Prayers Time section has index 0 and you set height of 45 pixels to it, when the next section has index 1 and height of 20, which is apparently not what you want.
Hi hope someone can help.
I currently have a tableview which has a set of sections, in my titleForHeaderInSection i am returning a string that includes a sum of values contained in the section cells to display in the section header. This is fine but when i update a cell value i want the titleForHeaderInSection to update and refresh my sum of values. At the moment the user needs to scroll the header out of sight then back in for it to refresh. I have been googling to see if i could find a solution seen a few examples that suggest including a label in the view for header but i need the sections to be dynamic so cant create labels for each section, i have also tried using the reloadsection but this doesent work properly either and the tableview reloaddata is to much of a performance hit to do each time a value changes in a tableview cell.
my current code for my titlerForHeaderInSection is
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
int averageScoreTotal, _total;
averageScoreTotal = 0;
_total = 0;
for (BlkCon_BlockToConstructionType *sPC in sectionInfo.objects)
{
_total = [sPC.compositionPc integerValue];
averageScoreTotal += _total;
}
return [NSString stringWithFormat: #"(Total Composition for Group %d)", averageScoreTotal];
}
Thanks in advance for any help
You can use UITableView's -reloadSections:... method with the correct section. That will reload the section header, too.
If you don't want to use that method, because your table view stops scrolling for a moment or one of the table view cells is first responder, you have to use a custom header view for the section containing a label.
1) Implement -tableView:heightForHeaderInSection: and -tableView:viewForHeaderInSection:
- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return tableView.sectionHeaderHeight;
}
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
CGFloat height = [self tableView:tableView heightForHeaderInSection:section];
NSString *title = [self tableView:tableView titleForHeaderInSection:section];
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, height)];
containerView.backgroundColor = tableView.backgroundColor;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(19, 7, containerView.bounds.size.width - 38, 21)];
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont boldSystemFontOfSize:17];
label.shadowOffset = CGSizeMake(0, 1);
label.shadowColor = [UIColor whiteColor];
label.text = title;
label.textColor = [UIColor colorWithRed:0.265 green:0.294 blue:0.367 alpha:1];
[containerView addSubview:label];
return containerView;
}
2) Update the label directly by changing its text property. You'll have to create an iVar for the labels or better use an array to store them, so you can access them when you want to update the section header's text.
3) If you want to make the header flexible in height, set the numberOfLines property of the label to 0 so that it has indefinite lines and make sure the -tableView:heightForHeaderInSection: returns the correct height.
In order to update the section header's height use
[self.tableView beginUpdates];
[self.tableView endUpdates];
Good luck,
Fabian
Edit:
The code above assumes you're using ARC.
After lots of searching, I can't seem to find what I'm looking for.
I have a UITableview where some of the sections may be blank to begin with. Here's a picture to help get an idea of what I'm talking about. I want to have some TEXT (not a table cell) in the middle between the footer and the header. Is there anything that I may have overlooked?
What I did was create a UILabel with the same size as the tableview and add it to the tableview, something like:
UILabel* emptyLabel = [[UILabel alloc] init];
emptyLabel.textAlignment = UITextAlignmentCenter;
emptyLabel.backgroundColor = [UIColor clearColor];
emptyLabel.frame = self.tableView.bounds;
emptyLabel.text = #"Empty";
[self.tableView addSubview:emptyLabel];
You can then use the hidden property to show it or hide it, e.g. emptyLabel.hidden = TRUE;
Because of the nature of UITableViews, I'm not sure you could achieve replacing the UITableCell view with something else. However there's no reason you can't completely alter the table cell itself to look like a plain UITextLabel and not a cell! You could do something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
/* Initial setup here... */
if (thisCellHasNoDataYet) {
// Prevent highlight on tap
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
cell.backgroundColor = [UIColor clearColor];
cell.textLabel.textColor = [UIColor blackColor];
cell.textLabel.text = #"TEXT YOU WANT THE 'CELL' TO DISPLAY";
// etc...
}
else {
// Otherwise we have data to display, set normal cell mode
[cell setSelectionStyle:UITableViewCellSelectionStyleBlue];
cell.backgroundColor = [UIColor whiteColor];
// etc...
}
The benefit here is that once your condition is met, you just have to set the boolean (I used thisCellHasNoDataYet) to TRUE and call reloadData on your table!