Saturday, September 24, 2011

Centering the text in a section header - not trivial!

Ok, just a quick post on changing the background color on a table header. I'm going to rely on the Android version for the color. Let's see if we can figure out what went on with that.

Ok, just looking at it and comparing, I want to do 3 things with the header (section header, I think). The first is to make it transparent. The second is to change to to the same font color as on the Android. The third is to center it.

I also want to change the font color for the table rows, and make them transparent.

This post

http://www.iphonedevsdk.com/forum/iphone-sdk-development/5172-font-size-color-tableview-header.html

talks about changing the section header.

It's very similar to code I already have:

(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {

// Create label with section title
headerLabel = [[[UILabel alloc] init] autorelease];
headerLabel.textAlignment = UITextAlignmentCenter;
headerLabel.frame = CGRectMake(20, 6, 300, 30);
headerLabel.backgroundColor = [UIColor clearColor];
headerLabel.textColor = [UIColor brownColor];
headerLabel.font = [UIFont fontWithName:@"Helvetica-BoldOblique" size:45.0];

// support line break mode for multiline
headerLabel.lineBreakMode = UILineBreakModeWordWrap;

// 0 means any number of lines - necessary for multiline
headerLabel.numberOfLines = 0;

headerLabel.text = currentQuestion.questionKanji;

// very important!
[headerLabel sizeToFit];

// Create header view and add label as a subview
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, SectionHeaderHeight)];
view.backgroundColor = [UIColor clearColor];
[view autorelease];

[view addSubview:headerLabel];

return view;
}


So, it create a label, adds it as a subview to view, and then returns the view to be displayed. I've changed the color to brown for now, and changed the background color to clearColor on both the label and the view. Let's check it out.



Ok, we've made some progress. I'm not sure why it's not completely clear - is there an alpha factor at work? I was mucking around with that yesterday. But first, let's center the text.

Well, if I get rid of the size to fit, it centers - but becomes much smaller.

I saw this class posted on SO:

@interface UILabel (BPExtensions)
- (void)sizeToFitFixedWidth:(CGFloat)fixedWidth;
@end

@implementation UILabel (BPExtensions)


- (void)sizeToFitFixedWidth:(CGFloat)fixedWidth
{
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, fixedWidth, 0);
self.lineBreakMode = UILineBreakModeWordWrap;
self.numberOfLines = 0;
[self sizeToFit];
}
@end


I'm not sure about the self.frame - but I can hardcode it for now. But it's just doing the same type of things I'm doing. It's not setting it to centered.

This is a tricky one. The label frame is created the CGRectMake, which has hardcoded numbers.

Here's some info on CGRectMake and CGSize, which are somehow unavailable in Apple's documentation, possibly because they come from C originally or something:

http://iphonedevelopertips.com/c/cgrect-cgsize-and-cgpoint.html

Digging into development of iPhone applications, you’ll eventually encounter references to CGRect, CGSize, and CGPoint. These references are to C structures (see this post for more information on structures). This post will provide a high-level view of what comprises CGRect and its counterparts. Here is how CGRect is defined:


struct CGRect {
CGPoint origin;
CGSize size;
};
typedef struct CGRect CGRect;


Ah hah. So, CGRect contains CGSize.

Going a little further, we can find that CGPoint and CGSize are defined as follows:



struct CGPoint {
CGFloat x;
CGFloat y;
};
typedef struct CGPoint CGPoint;

struct CGSize {
CGFloat width;
CGFloat height;
};
typedef struct CGSize CGSize;


Ok - so CGSize is the height and width.

So, if I use this code from my "tableView:heightForHeightInSection" method:

NSString * labelText = currentQuestion.questionKanji;

// set a font size
UIFont *labelFont = [UIFont fontWithName:@"Helvetica" size:30.0];

// get a constraint size - not sure how it works
CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);

// calculate a label size - takes parameters including the font, a constraint and a specification for line mode
CGSize labelSize = [labelText sizeWithFont:labelFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];


This will give me the height and width for my frame.

So after the code above, I can do this:


float labelHeight = labelSize.height;
float labelWidth = labelSize.width;


Then do this:

headerLabel.frame = CGRectMake(20, 6, labelHeight, labelWidth);


Well, the part of the problem was that height I was setting for the font (for the UILabel) in the tableView:viewForHeaderInSection was different than that which I was using in the tableView:HeightForHeaderInSection part. So that's fixed by changing the font size to be 35 for both, and use the calculated label height when creating the rect:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {

CGSize labelSize;
labelSize = [self getLabelSize];

float labelHeight = labelSize.height;
float labelWidth = labelSize.width;


// Create label with section title
headerLabel = [[[UILabel alloc] init] autorelease];
headerLabel.textAlignment = UITextAlignmentCenter;


headerLabel.frame = CGRectMake(20, 6, 250, labelHeight);


headerLabel.backgroundColor = [UIColor clearColor];
headerLabel.textColor = [UIColor brownColor];
headerLabel.font = [UIFont fontWithName:@"Helvetica-BoldOblique" size:35.0];
// support line break mode for multiline
headerLabel.lineBreakMode = UILineBreakModeWordWrap;


headerLabel.text = currentQuestion.questionKanji;

// Create header view and add label as a subview
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, SectionHeaderHeight)];
view.backgroundColor = [UIColor clearColor];

[view autorelease];
[view addSubview:headerLabel];

return view;
}


And here's the method to calculate the label size:


- (CGSize) getLabelSize {
NSString * labelText = currentQuestion.questionKanji;

// set a font size
UIFont *labelFont = [UIFont fontWithName:@"Helvetica" size:35.0];

// get a constraint size - not sure how it works
CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);

// calculate a label size - takes parameters including the font, a constraint and a specification for line mode
CGSize labelSize = [labelText sizeWithFont:labelFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
return labelSize;
}



And here's where we'll leave it for now:

No comments:

Post a Comment