I have the following code which draws a separator line and text for a UITableViewCell. It looks fine but when I scroll off screen then back, the separator line is gone but the text is still fine. Any ideas?
static NSString *aProgressIdentifier = #"CustomerCell";
UITableViewCell *aCustomerCell = [iTableView dequeueReusableCellWithIdentifier:aProgressIdentifier];
if (!aCustomerCell) {
aCustomerCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:aProgressIdentifier] autorelease];
aCustomerCell.contentView.backgroundColor = [UIColor whiteColor];
UIImageView *aLine = [[UIImageView alloc] initWithFrame:CGRectMake(0, 72, 800, 1)];
aLine.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1.0];
[aCustomerCell addSubview:aLine];
[aLine release];
}
CMACustomer *aCustomerObject = aCellObject;
aCustomerCell.textLabel.text = aCustomerObject.customerFullName;
aCustomerCell.detailTextLabel.text = nil;
aCell = aCustomerCell;
Try to add the "aLine" image view as subview of the contentView and not the whole table itself. Probably when the cell is reused and then layoutSubviews is called again, the contentView overlaps (white background) your aLine. Infact consider that iOS default cells have their subviews dynamically redrawn and resized each time they are displayed on screen.
So I would try this:
[aCustomerCell.contentView addSubview:aLine];
If this doesn't work, what can you do is to remove the contentView completely and add your own custom subviews (do this inside the if(!aCustomerCell) and not outside unless you will not get the benefits of the cell re-use):
if (!aCustomerCell) {
aCustomerCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:aProgressIdentifier] autorelease];
[cell.subviews makeObjectsPerformSelector:#selector(removeFromSuperview)];
UIImageView *aLine = [[UIImageView alloc] initWithFrame:CGRectMake(0, 72, 800, 1)];
aLine.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1.0];
[aCustomerCell.contentView addSubview:aLine];
[aLine release];
}
Finally another check is verify that the cell height is > 72 (it seems a trivial check but its often source of headaches!).
The table view is using a pool of cells, so you can't be sure which one you're getting for any given index path. You can use the cell or the content view, but be sure to add only one of your custom lines per cell.
UIImageView *aLine = (UIImageView *)[cell viewWithTag:64];
if (!aLine) {
// etc.
UIImageView *aLine = [[UIImageView alloc] initWithFrame:CGRectMake(0, 72, 800, 1)];
aLine.tag = 64;
[cell addSubview:aLine];
//
}
// other formatting logic here, you can also hide/show aLine based on biz logic
try adding it to the contentView
[aCustomerCell.contentView addSubview:aLine]
Related
I need to display separator line in iOS 7 same like iOS 6 (as my image 2). I am using below code in CellForRowAtIndexPath:
UIView* separatorLineView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 1)];
separatorLineView.backgroundColor = [UIColor colorWithRed:229/255.0 green:229/255.0 blue:229/255.0 alpha:1.0];
[cell.contentView addSubview:separatorLineView];
UIView *customColorView = [[UIView alloc] init];
customColorView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"cell_highlighted.png"]];
cell.selectedBackgroundView = customColorView;
cell.backgroundColor=[UIColor clearColor];
//Separation style for iOS7
if ([tableView respondsToSelector:#selector(setSeparatorInset:)]) {
[tableView setSeparatorInset:UIEdgeInsetsZero];
}
return cell;
I am getting output as below image:
But my output should like below image for both IOS 6 and 7:
Can anyone please help me how to achieve this? Thanks..
contentView doesn't always have the same size as the cell itself, add separator view on top of the cell view above the content view:
separatorLineView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[cell insertSubview:separatorLineView aboveSubview:cell.contentView];
UITableView has a property separatorInset. Use that to set the insets of the table view separators to zero to let them span the full width of the screen.
[tableView setSeparatorInset:UIEdgeInsetsZero];
OR
You can set separator inset property in xib also. Change it to custom. And make both left and right values to zero.
I created UIViewController in Storyboard and added tableview as a Subview. Its working fine. In that tableview I added cells programatically and each cell contains UITextFields or UITextView. UITextFields are working fine. But UITextViews have some troubles. EX: When I add text to UITextView then bellow UITextViews are overlapped. why is that ? I tried to sort out whole day. But still I couldn't. :(
case cellResponseNote:
cell = [tableView.tableView dequeueReusableCellWithIdentifier:CellIdentifierResponseNote];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifierResponseNote];
cell.frame = CGRectMake(0, 0, cell.frame.size.width, cellNotesHeight);
//cell.frame = CGRectMake(0, 0, cell.frame.size.width, cellNotesHeight);
if (!self.txtVwResponseNote) {
// self.txtVwResponseNote = [[UITextView alloc] initWithFrame:cell.frame];
self.txtVwResponseNote = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, cell.frame.size.width, cellNotesHeight)];
[self.txtVwResponseNote setScrollEnabled:NO];
[self.txtVwResponseNote setAutoresizingMask:UIViewAutoresizingNone];
[self.txtVwResponseNote setDelegate:self];
[self.txtVwResponseNote setFont:[UIFont systemFontOfSize:14]];
[self.txtVwResponseNote setInputAccessoryView:self.keyboardToolbar];
[self setupMailData:indexPath.row];
}
}
self.txtVwResponseNote.editable = !(self.isMailForReview);
// [cell.contentView addSubview:self.txtVwResponseNote];
[cell addSubview:self.txtVwResponseNote];
contentSubview = self.txtVwResponseNote;
In this image bottom You can see three cells. ( bellow Footer) When I add text value for top text view. Then overlap the next text view.
Bellow image you can see only two textviews. Bottom text view is not showing.
So what should I do ?
First of all as an answer try setting the height of the cell by following method.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
case cellResponseNote:
return cellNotesHeight;
default:
return defaultHeight;
}
Also I recommend you not to share the textview property. Instead try modifying your code like this and see whether your code works.
case cellResponseNote:
cell = [tableView.tableView dequeueReusableCellWithIdentifier:CellIdentifierResponseNote];
UITextView *txtVwResponseNote = nil;
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifierResponseNote];
cell.frame = CGRectMake(0, 0, cell.frame.size.width, cellNotesHeight);
//cell.frame = CGRectMake(0, 0, cell.frame.size.width, cellNotesHeight);
//if (!self.txtVwResponseNote) {
// self.txtVwResponseNote = [[UITextView alloc] initWithFrame:cell.frame];
txtVwResponseNote = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, cell.frame.size.width, cellNotesHeight)];
[txtVwResponseNote setScrollEnabled:NO];
[txtVwResponseNote setAutoresizingMask:UIViewAutoresizingNone];
[txtVwResponseNote setDelegate:self];
[txtVwResponseNote setFont:[UIFont systemFontOfSize:14]];
[txtVwResponseNote setInputAccessoryView:self.keyboardToolbar];
[txtVwResponseNote setTag:100];
//}
} else {
txtVwResponseNote = (UITextView *)[cell viewWithTag:100]
}
[self setupMailData:indexPath.row];
txtVwResponseNote.editable = !(self.isMailForReview);
// [cell.contentView addSubview:txtVwResponseNote];
[cell addSubview:self.txtVwResponseNote];
contentSubview = self.txtVwResponseNote;
It gets repeated because you added it to the cell as a subview, and then reuse the cell. Add it as a accessoryView of the cell instead, and set it to nil for the cell's that dont need it.
cell.accessoryView = self.txtVwResponseNote;
And in all other cells, set accessoryView to nil.
cell.accessoryView = nil;
cellForRowAtIndexPath:
CGRect nameValueRect = CGRectMake(80, 5, 200, 15);
UILabel *nameValue = [[UILabel alloc] initWithFrame:
nameValueRect];
nameValue.tag = kNameValueTag;
[cell.contentView addSubview:nameValue];
[nameValue release];
...
NSUInteger row = [indexPath row];
NSDictionary *rowData = [self.computers objectAtIndex:row];
UILabel *name = (UILabel *)[cell.contentView viewWithTag:
kNameValueTag];
name.text = [rowData objectForKey:#"Name"];
This code is from a tutorial that I'm using which creates a subview within the cell to add some text.
However, what I want to do is instead of adding text I will place an image.
I tried UIImageView *posterValue = [[UIImageView alloc] initWith... oh there's no initWithFrame for UIImageView.
Perhaps, someone can explain the process for an image. Do I even need to set the frame size for a UIImageView? I would need to position it.
EDIT:
my new code:
UIImageView *posterValue = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,105,175)];
posterValue.tag = kPosterValueTag;
[cell.contentView addSubView:posterValue];
[posterValue release];
addSubView is not working for UIImageView. Says UIView may not respond to addSubView
It's addSubview not addSubView - case matters.
I want to add a table header (not section headers) like in the contacts app for example:
exactly like that - a label beside an image above of the table.
I want the all view be scrollable so I can't place those outside of the table.
How can I do that?
UITableView has a tableHeaderView property. Set that to whatever view you want up there.
Use a new UIView as a container, add a text label and an image view to that new UIView, then set tableHeaderView to the new view.
For example, in a UITableViewController:
-(void)viewDidLoad
{
// ...
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(XXX, YYY, XXX, YYY)];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(XXX, YYY, XXX, YYY)];
[headerView addSubview:imageView];
UILabel *labelView = [[UILabel alloc] initWithFrame:CGRectMake(XXX, YYY, XXX, YYY)];
[headerView addSubview:labelView];
self.tableView.tableHeaderView = headerView;
[imageView release];
[labelView release];
[headerView release];
// ...
}
You can do it pretty easy in Interface Builder. Just create a view with a table and drop another view onto the table. This will become the table header view. Add your labels and image to that view. See the pic below for the view hierarchy.
In Swift:
override func viewDidLoad() {
super.viewDidLoad()
// We set the table view header.
let cellTableViewHeader = tableView.dequeueReusableCellWithIdentifier(TableViewController.tableViewHeaderCustomCellIdentifier) as! UITableViewCell
cellTableViewHeader.frame = CGRectMake(0, 0, self.tableView.bounds.width, self.heightCache[TableViewController.tableViewHeaderCustomCellIdentifier]!)
self.tableView.tableHeaderView = cellTableViewHeader
// We set the table view footer, just know that it will also remove extra cells from tableview.
let cellTableViewFooter = tableView.dequeueReusableCellWithIdentifier(TableViewController.tableViewFooterCustomCellIdentifier) as! UITableViewCell
cellTableViewFooter.frame = CGRectMake(0, 0, self.tableView.bounds.width, self.heightCache[TableViewController.tableViewFooterCustomCellIdentifier]!)
self.tableView.tableFooterView = cellTableViewFooter
}
You can also simply create ONLY a UIView in Interface builder and drag & drop the ImageView and UILabel (to make it look like your desired header) and then use that.
Once your UIView looks like the way you want it too, you can programmatically initialize it from the XIB and add to your UITableView. In other words, you dont have to design the ENTIRE table in IB. Just the headerView (this way the header view can be reused in other tables as well)
For example I have a custom UIView for one of my table headers. The view is managed by a xib file called "CustomHeaderView" and it is loaded into the table header using the following code in my UITableViewController subclass:
-(UIView *) customHeaderView {
if (!customHeaderView) {
[[NSBundle mainBundle] loadNibNamed:#"CustomHeaderView" owner:self options:nil];
}
return customHeaderView;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Set the CustomerHeaderView as the tables header view
self.tableView.tableHeaderView = self.customHeaderView;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0,0,tableView.frame.size.width,30)];
headerView.backgroundColor=[[UIColor redColor]colorWithAlphaComponent:0.5f];
headerView.layer.borderColor=[UIColor blackColor].CGColor;
headerView.layer.borderWidth=1.0f;
UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 5,100,20)];
headerLabel.textAlignment = NSTextAlignmentRight;
headerLabel.text = #"LeadCode ";
//headerLabel.textColor=[UIColor whiteColor];
headerLabel.backgroundColor = [UIColor clearColor];
[headerView addSubview:headerLabel];
UILabel *headerLabel1 = [[UILabel alloc] initWithFrame:CGRectMake(60, 0, headerView.frame.size.width-120.0, headerView.frame.size.height)];
headerLabel1.textAlignment = NSTextAlignmentRight;
headerLabel1.text = #"LeadName";
headerLabel.textColor=[UIColor whiteColor];
headerLabel1.backgroundColor = [UIColor clearColor];
[headerView addSubview:headerLabel1];
return headerView;
}
I want to remove the default white background of UITableViewCell like I want the background of the cell being transparent so that it shows the actual background of the window.
I Got it.
UIView *backView = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
backView.backgroundColor = [UIColor clearColor];
cell.backgroundView = backView;