I am using a static grouped UITableView to display some settings to the user. Above each group I have a header with a title.
I want to customize the look of the table view and I want to use this look throughout the whole application. Therefore I have subclassed the UITableViewController and my TableViewControllers are inheriting from my subclass.
Is there a way to enter a title for a header using Interface Builder and in my UITableViewController subclass change the look of the header?
I tried retrieving the title using [self tableView:self.tableView titleForHeaderInSection:section] but quickly after posting this question I realized it should have been called from super. Therefore:
[super tableView:self.tableView titleForHeaderInSection:section].
The header can be customized using
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
NSString *title = [super tableView:self.tableView titleForHeaderInSection:section];
if (title.length == 0) return nil;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 40)];
label.textColor = [UIColor whiteColor];
label.backgroundColor = [UIColor clearColor];
label.text = title;
return label;
}
Related
I want to display a table with custom header titles.
The table view is attached to a controller class that implements the tableview delegate and data source protocols but is not a subclass of UIViewController because the table is a subview to be displayed above another tableview.
some snippets of my code:
The tableview is created programmatically:
_myListView = [[UITableView alloc] initWithFrame:tableFrame style:UITableViewStyleGrouped];
[_myListView setDataSource:self.myListController];
[_myListView setDelegate:self.myListController];
[_myListView setBackgroundColor:darkBackgroundColor];
where myListController is a strong property in the class.
For the number of rows in sections:
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
…
return count;
}
The number of sections:
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [someDelegate sectionCount];
}
For the custom Header View:
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView* headerView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, SectionHeaderHeight)];
UILabel* sectionHeaderTitle = [[UILabel alloc] initWithFrame:CGRectMake(20, 3, 300, 24)];
[headerView setBackgroundColor:[UIColor clearColor]];
sectionHeaderTitle.text = [self myTitleForHeaderInSection:section];
sectionHeaderTitle.textColor = [UIColor whiteColor];
sectionHeaderTitle.textAlignment = UITextAlignmentLeft;
[headerView addSubview:sectionHeaderTitle];
return headerView;
}
For the custom headerViewHeight (as required since iOS5):
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if ( [self tableView:tableView numberOfRowsInSection:section] > 0) {
return SectionHeaderHeight;
} else {
return 0;
}
}
Sadly, the tableview does not display any section headers just as if I would return nil.
However, I have checked with a breakpoint, that the code actually returns an UIView.
Everything else works fine.
What am I missing? PLease, don't hesitate to make me feel ashamed of my self.
I don't really understand why you want to use a custom view, and not the "standard" one ? You may have your reasons, but I don't see anything in your code telling me why :)
I would personally just use this:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (section == 0) return #"First section header title";
if (section == 1) return #"Second section header title";
else return nil;
}
Tell me if that's not what you're looking for !
I seem to have found a solution:
I have created a lazy loading strong property for each header view I want to display. (luckily there are only three)
Now the views are shown.
It seems that the header views got deallocated without the strong references before the table was rendered.
Could it be that there is a connection to the class implementing the table view delegate and data source protocols is not a UIViewController?
Text Color you change it to Black color and check once.
sectionHeaderTitle.textColor = [UIColor blackColor];
you try this code this work on my side :-)
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *view=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 24)];
UIImage *myImage = [UIImage imageNamed:#"SectionBackGround.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:myImage];
imageView.frame = CGRectMake(0,0,320,24);
UIImage *imageIcon = [UIImage imageNamed:#"SectionBackGround.png"];
UIImageView *iconView = [[UIImageView alloc] initWithImage:myImage];
iconView.frame = CGRectMake(0,0,320,24);
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, 24)];
label.text = [tableView.dataSource tableView:tableView titleForHeaderInSection:section];
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont boldSystemFontOfSize:14];
[view addSubview:imageView];
[view addSubview:iconView];
[view addSubview:label];
return view;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 24;
}
I am trying to create a custom UITableView that is contained within another view. I have been able to get the view set up almost like the way that I want it. I am just wondering however how come the two methods (tableView:cellForRowAtIndexPath and tableView:didSelectRowAtIndexPath) that I need the most are not getting called. Note that I am not using UITableViewController, but I am using UIViewController to control the tableView.
And here is a snippet of my code
- (void)loadView {
CGRect applicationFrame = [[UIScreen mainScreen] applicationFrame];
UIView * contentView = [[UIView alloc] initWithFrame:applicationFrame];
contentView.backgroundColor = [UIColor whiteColor];
self.view = contentView;
UIImageView * backgroundImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"mainBackground.jpeg"]];
[self.view addSubview:backgroundImageView];
CGRect tableFrame = CGRectMake(40, 40, 240, 310);
self.listView = [[UITableView alloc] initWithFrame:tableFrame];
self.listView.dataSource = self;
self.listView.delegate = self;
self.listView.scrollEnabled = NO;
self.listView.rowHeight = 50;
self.listView.backgroundColor = [UIColor clearColor];
self.listView.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cellBgMid"]];
[self.view addSubview:self.listView];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"cellRow %#", indexPath.row);
return [super tableView:tableView cellForRowAtIndexPath:indexPath];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"Did Select Row%#", indexPath.row);
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
}
Did you implement the -tableView:numberOfRowsInSection: ? Without it you won't be able to have any cells in your table view.
You need to implement the tableviewdelegate and tableviewsource protocols. You will need to add an IBOutlet to UITableView that is the reference outlet in xib for the table vie and set the data source as the your UIView controller once you add the protocols.
Sorry I see your not using xib. It's curious your not getting a warning on the line where your setting the data source and delegate, so you may already have your protocols there.
I am new to iPhone development. I have created one view controller and I used grouped table view. Now I want to display the header view in my viewcontroller with image and labels. Please guide me and help me out in this problem.
Thanks.
Do you mean a headerView or a sectionHeaderView? You can add subviews to the headerView in the viewDidLoad method:
- (void)viewDidLoad {
[super viewDidLoad];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 300, 225)];
label.text = #"BlaBla";
[self.tableHeaderView addSubview:label];
}
You specify size and position of the label with the initWithFrame method, and add the label as subview to the tableHeaderView - you can do this with multiple labels.
If you mean the sectionHeader you have to implement the tableView:viewForHeaderInSection: method, where you have to create a new view, and add different subviews to it:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 300, 40)];
label.text = #"BlaBla";
[view addSubview:label];
[label release];
return [view autorelease];
}
In this case you also have to implement the method tableView:heightForHeaderInSection: which has to return the height of the view you create in the above method:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 50.0f;
}
I've got an annoying problem in my tableview. I was able to achive color-changing cells (blue/white/blue/...), but now I'm in trouble with my text, which has a white background on the blue cells.
I've tried for testing to set a background color to red:
// try to set the backgroundcolor of the text ???
cell.textLabel.text.backgroundColor = [UIColor redColor];
which doesn't work; hmph.
Please have a look at my code below; can anybody tell me what's wrong and how I can solve my problem by giving the text a transparent background?
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell
cell.textLabel.text=[RssFeedNodes objectAtIndex:indexPath.row];
// try to set the backgroundcolor of the text ???
cell.textLabel.text.backgroundColor = [UIColor redColor];
// show image in cell
NSString *imageName=#"rss.png";
cell.imageView.image=[UIImage imageNamed:imageName];
// changing colors in cells
NSInteger row = [indexPath row];
if (row % 2){
cell.contentView.backgroundColor = [UIColor whiteColor];
}
else {
cell.contentView.backgroundColor = [UIColor colorWithRed:0.90f green:0.95f blue:1.0f alpha:1.0f];
}
return cell;
}
Your answer is found (and described very well) here: http://undefinedvalue.com/2009/11/02/easy-gradient-backgrounds-uitextviewcells
My brief summary of the solution: Subclass the UITableViewCell, and then use your subclass when creating instances in cellForRowAtIndexPath.
You then need to override just one method (setSelected) in your subclass UITableViewCell:
(void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
for (UIView *view in self.contentView.subviews) {
view.backgroundColor = [UIColor clearColor];
}
}
The reason appears to be that the built-in UITableViewCell class will set the label background to white (or selected color) when being displayed based on the selection state in the table in the setSelected method. Substitute your own, call the base class implementation, then set your subview backgrounds to clear in order to let your contentView background shine through.
text has no background, but textLabel has. so
[[cell textLabel] setBackground:[UIColor redColor]];
You'll need to add your own UILabel label onto the cell, and set the background colour of that to transparent. For some reason the label that a table cell has does not have a settable background colour.
Something like:
UILabel* label = [[UILabel alloc] init];
label.frame = CGRectMake( 20, 10, 200, 22 );
label.backgroundColor = [UIColor clearColor];
label.opaque = NO;
label.text = #"your text here:";
[cell addSubview:label];
[label release];
In this example I've set the frame for the label fairly arbitrarily (well not, actually, this was modified from some of my own real code). You may need to be more dynamic with the sizing, in which case you'll probably need to subclass the cell and override setFrame to keep the label's frame in sync. But hardcoded values should get you going for now.
#define LABEL_TAG 99
// whatever your label rect size should be... change as appropriate
UIlabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300.0, 30.0)];
label.tag = LABEL_TAG;
// set up alignment, font, autoresizemask, etc.
label.backgroundColor = [UIColor clearColor];
label.opaque = NO;
[cell.contentView addSubview:label];
[label release];
Something to watch out for is that you're not adding your own label to a reuseable table cell more than once. By setting a known view.tag property you can get at (or discover existence of) the UILabel view. [cell viewWithTag:LABEL_TAG]
Whenever you dequeue a reuseable cell, first get the reference to your label view, then do what you would normally do if you were using the UITableCell's textLabel.
For an iPhone, I've got a UITableView that is grouped, has one section, and in which I've set up a section header that's a UILabel object from the nib. When the table view displays, the header shows up as a stripe of solid black -- no text.
In heightForHeaderInSection I've set the height to be the frame.size.height of the UILabel object. When I change the height in IB, the black stripe's height changes. So I know that the .m file has latched on to the right UILabel object.
In the debugger, in viewForHeaderInSection, it seems that the width of the UILabel object is zero, and the height is 1079574528, and the text is null.
Any thoughts on what I'm doing wrong?
Not sure what you're doing wrong, but here is some example code that might help (from a post on my blog):
#define SectionHeaderHeight 40
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
if ([self tableView:tableView titleForHeaderInSection:section] != nil) {
return SectionHeaderHeight;
}
else {
// If no section header title, no section header needed
return 0;
}
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
NSString *sectionTitle = [self tableView:tableView titleForHeaderInSection:section];
if (sectionTitle == nil) {
return nil;
}
// Create label with section title
UILabel *label = [[[UILabel alloc] init] autorelease];
label.frame = CGRectMake(20, 6, 300, 30);
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor colorWithHue:(136.0/360.0) // Slightly bluish green
saturation:1.0
brightness:0.60
alpha:1.0];
label.shadowColor = [UIColor whiteColor];
label.shadowOffset = CGSizeMake(0.0, 1.0);
label.font = [UIFont boldSystemFontOfSize:16];
label.text = sectionTitle;
// Create header view and add label as a subview
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, SectionHeaderHeight)];
[view autorelease];
[view addSubview:label];
return view;
}
I had the same issue and haven't quite figured why the black bar..
BUT, instead of providing the header and footer views in delegate methods,
if i set values for tableView.tableHeaderView and tableView.tableFooterView, its all fine !
Can you post the code for your heightForHeaderInSection and your viewForHeaderInSection functions? The theory behind what you're doing sounds correct, but without seeing the code, it would be nearly impossible to figure out the issue...
It sounds like you place a label on the view in IB and are trying to use that as your header view - which is not the proper way of doing things. If you aren't using viewForHeaderInSection, then give that a try.. like this:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UILabel *lbl;
lbl.text = #"Header for The Only Section";
//define other properties for the label - font, shadow, highlight, etc...
return lbl;
}
3.1.3 doesnt like [UIColor clearColor]; try using the same background color as your tableview
I observed same behavior when refreshing after datasource is loaded.
I noticed this was due to the way i was refreshing table view.
//[self loadView]; this caused the section header to go black.
[self.tableView reloadData]; // this works!