Custom Tableview section header is all black - objective-c

I have a tableview section header, for which I'd like to add a custom view. When the tableview loads, it appears black, shown here: http://postimage.org/image/luluolc57/ When I start scrolling, and the header "sticks" to the top of the screen/navbar, it becomes just how I want it - shown here http://postimage.org/image/lek98nxud/
Basically, I'd like this view to be transparent with this gray tinted circle on it, so the tableview background shows through. here's the respective code.
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
return [[SummaryView alloc] init];
}
- (void)drawRect:(CGRect)rect
{
CGRect tintSize = CGRectMake(0.0, 0.0, self.bounds.size.height, self.bounds.size.height);
[[UIImage imageNamed:#"Circular Tint.png"] drawInRect:tintSize];
}

Does it work as expected with a standard UILabel?
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UILabel* label = [[UILabel alloc] init];
[label setText:#"TEST"];
return label;
}
If it does, you can slowly try transitioning from that and see at what point the problem arises. It might be related to the size of your custom view when it is alloc and init. Maybe initWithFrame would solve it.

Related

UITableView & Sections - to detect if a section header is stays on top

I need this because I need to change the background color of a section. For example, if section at the top then blue green otherwise.
I have tried many things but I am with my ideas at the end.
Try this
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
{
// Background color
view.backgroundColor = section == 0 ? [UIColor blueColor] : [UIColor greenColor];
// Another way to set the background color
// Note: does not preserve gradient effect of original header
// UITableViewHeaderFooterView *header = (UITableViewHeaderFooterView *)view;
// header.contentView.backgroundColor = [UIColor blackColor];
}
Considering top means 1st section.
Edit
If you want to change color according to scrolling and identifying which section is on top and which is not then you have to implement UIScrollViewDelegate so that you can handle scrolling delegates. You can try something like this
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
NSIndexPath *firstVisibleIndexPath = [[self.tableView indexPathsForVisibleRows] objectAtIndex:0];
NSLog(#"first visible cell's section: %i, row: %i", firstVisibleIndexPath.section, firstVisibleIndexPath.row);
}
References: UIScrollViewDelegate implementation and Detecting top cell in TableView
Try this:
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
{
NSArray* visibleCellIndexPaths = [tableView indexPathsForVisibleRows];
//Set all header views to have a blue background color.
[view setBackgroundColor:[UIColor blueColor]];
if(visibleCellIndexPaths.count > 0)
{
//Set the topmost visible section header view to have green background color.
[[tableView headerViewForSection:[visibleCellIndexPaths[0] section]] setBackgroundColor:[UIColor greenColor]];
}
}
Just check if the frame of the section header you're looking for has moved to the top.
Swift version of #faisal Ali answer
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
view.backgroundColor = section == 0 ? UIColor.white : UIColor.clear
}

How to make UITextView in section header adjust its height to its content

I cannot get this to work. I am using autolayout on the current view controller. I have a UITableView that has section headers and each section header has UITextView that has text that varies in length depending on the section. I cannot make it enlarge its height automatically to fit the contents so there will be no need for scroll (its contents are attributed text)
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
//UITextView *tv = [[UITextView alloc] init];
//tv.editable = NO;
//tv.attributedText = [self millionaireResults][section][#"header"];
//return tv;
return [self millionaireResults][section][#"headerview"]; //this is a uitextview
}
// this did not workeither
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
UITextView *tv = [self millionaireResults][section][#"headerview"];
return tv.frame.size.height;
}
How can this problem be solved?
I updated the code per the suggestion of Michael below
Make your "UITextView *tv" object a property and then you can do something like this (assuming you only have exactly one section to your table view):
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return (self.tv.frame.size.height);
}
If you have more sections (which is appears you do), you should make that property a NSArray of UITextView objects.
This also means you need to set the contents of your "tv" object before "viewForHeaderInSection:" gets called.
This is the answer that worked for me
When you are creating the UITextView, you must set the scrollEnabled
to false.
Your UITextView must be given the width that covers horizontal space otherwise auto size calculation are off (sometimes it is sometimes it is not, i think depending on wordbreak or something, but it was inconsistent!) and only fixes itself if you rotate the device to force redraw
In the heightForHeaderInSection method, you must get the
sizeThatFits and return its height as the height of your text view
Here is the height calculation (I found this on this site http://www.raywenderlich.com/50151/text-kit-tutorial )
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
UITextView *tv1 = (UITextView *)[self millionaireResults][section][#"headerview"];
// sizethatfits calculates the perfect size for this UITextView
// if you gave your UITextView full width
CGSize goodsize = [tv1 sizeThatFits:tv1.frame.size];
return goodsize.height+4; // here 4 is not necessary, i just put it as an offset
}
Here is the code that creates those UITextView objects
for (int i = 0; i < [milarr count]; i++) {
UITextView *tv = [[UITextView alloc] init];
tv.editable = NO;
tv.attributedText = milarr[i];
// labelTopTitle and this table in question have same width in an autoLayouted view
// so i am giving width of labelTopTitle to let UITextView cover full available
// horizontal space
tv.frame = CGRectMake(0, 0, self.labelTopTitle.frame.size.width,FLT_MAX);
//tv.backgroundColor = [UIColor grayColor];
//tv.textContainerInset = UIEdgeInsetsZero;
tv.scrollEnabled = NO;
[results addObject:#{#"headerview": tv,
#"rows":#[...]
}
];
}

UITableViewCell content overlaps delete button when in editing mode in iOS7

I am creating a UITableView with custom UITableViewCells. iOS 7's new delete button is causing some problems with the layout of my cell.
If I use the "Edit" button, which makes the red circles appear I get the problem, but if I swipe a single cell it looks perfect.
This is when the Edit button is used:
[self.tableView setEditing:!self.tableView.editing animated:YES];
This is when I swipe a single cell:
As you can se my labels overlaps the delete button in the first example. Why does it do this and how can I fix it?
try using the accessoryView and editingAccessoryView properties of your UITableViewCell, instead of adding the view yourself.
If you want the same indicator displayed in both editing and none-editing mode, try setting both view properties to point at the same view in your uiTableViewCell like:
self.accessoryView = self.imgPushEnabled;
self.editingAccessoryView = self.imgPushEnabled;
There seems to be a glitch in the table editing animation in IOS7, giving an overlap of the delete button and the accessoryView when switching back to non-editing state. This seems to happen when the accesoryView is specified and the editingAccessoryView is nil.
A workaround for this glitch, seems to be specifying an invisible editingAccessoryView like:
self.editingAccessoryView =[[UIView alloc] init];
self.editingAccessoryView.backgroundColor = [UIColor clearColor];
The problem is that in edit mode the cell's contentView changes in size. So either you have to override layoutSubviews in your cell and support the different frame sizes
- (void) layoutSubviews
{
[super layoutSubviews];
CGRect contentFrame = self.contentView.frame;
// adjust to the contentView frame
...
}
or you take the bait and switch to autolayout.
First I thought setting contentView.clipsToBounds to YES could be an ugly workaround but that does not seem to work.
I've resolved this problem with set up constraints without width only leading and trailing
As tcurdt mentioned, you could switch to autolayout to solve this issue. But, if you (understandably) don't want to mess with autolayout just for this one instance, you can set the autoresizingMask and have that turned automatically into the appropriate autolayout constraints.
label.autoresizingMask = UIViewAutoresizingFlexibleWidth;
Just use this method in your custom TableViewCell class you can get the perfect answer,
Here self is UITableviewCell
- (void)layoutSubviews {
[super layoutSubviews];
for (UIView *subview in self.subviews) {
for (UIView *subview2 in subview.subviews) {
if ([NSStringFromClass([subview2 class]) isEqualToString:#"UITableViewCellDeleteConfirmationView"]) { // move delete confirmation view
[subview bringSubviewToFront:subview2];
}
}
}
}
And if any one want to adjust the Delete Button Size, Use the following Code
- (void)layoutSubviews {
[super layoutSubviews];
for (UIView *subview in self.subviews) {
for (UIView *subview2 in subview.subviews) {
if ([NSStringFromClass([subview2 class]) isEqualToString:#"UITableViewCellDeleteConfirmationView"]) { // move delete confirmation view
CGRect rect = subview2.frame;
rect.size.height = 47; //adjusting the view height
subview2.frame = rect;
for (UIButton *btn in [subview2 subviews]) {
if ([NSStringFromClass([btn class]) isEqualToString:#"UITableViewCellDeleteConfirmationButton"]) { // adjusting the Button height
rect = btn.frame;
rect.size.height = CGRectGetHeight(subview2.frame);
btn.frame = rect;
break;
}
}
[subview bringSubviewToFront:subview2];
}
}
}
}
Best way to remove this problem is that add an image in cell and set it in Backside.
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"bgImg.png"]];
imageView.frame = CGRectMake(0, 0, 320, yourCustomCell.frame.size.height);
[yourCustomCell addSubview:imageView];
[yourCustomCell sendSubviewToBack:imageView];
If your text would overlap the delete button then implement Autolayout. It'll manage it in better way.
One more case can be generate that is cellSelectionStyle would highlight with default color. You can set highlight color as follows
yourCustomCell.selectionStyle = UITableViewCellSelectionStyleNone;
Set your table cell's selection style to UITableViewCellSelectionStyleNone. This will remove the blue background highlighting or other. Then, to make the text label or contentview highlighting work the way you want, use this method in yourCustomCell.m class.
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
if (highlighted)
self.contentView.backgroundColor = [UIColor greenColor];
else
self.contentView.backgroundColor = [UIColor clearColor];
}
I hope you understand it in a better way.
Bringing to front UITableViewCellDeleteConfirmationView in the layoutSubviews of the custom cell works for me on iPhone, but not on iPad.
I have a UITableView in the master part of a splitViewController for the iPad, and in this case
the frame of the UITableViewCellDeleteConfirmationView is (768 0; 89 44), instead of (320 0; 89 44)
So I resize the frame in the layoutSubviews method and this works for me
- (void)layoutSubviews {
[super layoutSubviews];
for (UIView *subview in self.subviews)
{
for (UIView *subview2 in subview.subviews)
{
if ([NSStringFromClass([subview2 class]) isEqualToString:#"UITableViewCellDeleteConfirmationView"])
{
CGRect frame = subview2.frame;
frame.origin.x = 320;
subview2.frame = frame;
[subview bringSubviewToFront:subview2];
}
}
}
}
If you are putting content in the UITableViewCell's contentView, be sure you use self.contentView.frame.size.width and not self.frame.size.width in layoutSubviews.
self.frame expands width in editing mode, and will cause any content on the right to extend past the bounds of the contentView. self.contentView.frame stays at the correct width (and is what you should be using).
Try this: Might be you are setting cell setBackgroundImage in cellForRowAtIndexPath (Delegate Method). Do not set this here. Set your image in:
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { cell.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:#"cellList.png"]]; }
Enjoy Coding.
My solution is to move whole contentView to the left when Delete button showing:
override func layoutSubviews() {
super.layoutSubviews()
if editingStyle == UITableViewCellEditingStyle.Delete {
var rect = contentView.frame
rect.origin.x = self.showingDeleteConfirmation ? -15 : 38
contentView.frame = rect
}
}

iOS 7 Grouped Table viewForHeaderInSection label offset in section 1

I've implemented a custom viewForHeaderInSection as follows:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
CGRect sectionFrame = CGRectMake(0, 0, tableView.bounds.size.width, 30.0f);
float xInset = 16.0;
RTUTableHeaderView
*headerView =
[[RTUTableHeaderView alloc] initWithFrame:sectionFrame
andBackgroundColor:[UIColor clearColor]
FontColor:[RTUColorHelper kSettingsTableCellFontColor]
andFontSize:18.f
withLabelFrame:CGRectMake(xInset, 10.f, sectionFrame.size.width - xInset, 20)];
headerView.label.text = [self tableView:tableView titleForHeaderInSection:section];
return headerView;
}
This pushes the labels down by 10pts so that they sit closer to the relevant section. In iOS6 it looks fine, but for iOS7 the label in the first section header is around 10pts further up than the others. If I take away the 10pt offset, the label for the first section sits at the top of the headerView whereas the others are vertically-centered in their header frames.
I could just frig the values for section 0 if it's a bug but would obviously rather not and wanted to check that I haven't forgotten something else or done something wrong.
The section headers are all the same height, heightForRowAtIndexPath returns 44.f
So the only way I managed to fix this problem was to add an offset to the first section header:
if(section==0){
CGRect labelFrame = headerView.label.frame;
labelFrame.origin.y+=15.f;
[headerView.label setFrame:labelFrame];
}
If anyone has any better ideas I'd love to hear them!

How to modify the font size for the text in a grouped header of a table view?

I'm working witha simple tableview but I need to modify the font size for the text in the group header.
I've found this question on stackoverflow eferencing the tableview methods to override but I'm looking for an example of how I might modify the actual headers font size once I implement this method
Note: I'm able to modify the height of the header itself using interface builder but the font size appears to require some objective-c to modify this
Thank you in advance
Edit
here is what I have so far -it's not throwing an exception but the header itself doesn't show the text or font size I set on the label itself
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView* x = tableView.tableHeaderView;
UILabel* y = [[UILabel alloc] initWithFrame:CGRectMake(5, 0, 310, 0)];
y.font = [UIFont boldSystemFontOfSize:12.0];
y.text = #"ha";
[x addSubview:y];
[y release];
return x;
}
The header for a table may be set to any subclass of UIView. In particular, you can create a UILabel, set the text with your desired font size, then make the label the headerView.
Three potential problems with your edit:
Did you remember to implement tableView:heightForHeaderInSection:?
The height of your UILabel is currently 0.
When this method is called, tableView.tableHeaderView may not yet be defined.
My approach would be to declare UILabel *headerLabel and then add this to viewDidLoad:
headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(5, 0, 310, 15)];
headerLabel.font = [UIFont boldSystemFontOfSize:12.0];
headerLabel.text = #"Testing";
Then have
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 15.0;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
return headerLabel;
}