How to add uiview in uitableviewcell - objective-c

Hope all of you'll be fine.
I have a little issue in my application. I have a tableview with custom-cell. In my custom-cell class i made a uiview
UIView* cellView = [[UIView alloc] initWithFrame:self.contentView.frame];
cellView.backgroundColor = [UIColor grayColor];
[self.contentView addSubview:cellView];
Problem is uiview is not fitting in my cell frame properly. Cellforrow is as :
- (SummaryViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"cell";
SummaryViewCell *cell = (SummaryViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil)
{
cell = [[SummaryViewCell alloc] init];
}
cell.backgroundColor = [UIColor blueColor];
return cell;
}
I have tried initWithFrame:self.contentView.frame] but same problem happened (uiview appear in cell but cover only half of the cell), I also have tried cellView = [[UIView alloc] initWithFrame:CGRectMake(0,0,self.frame.size.width and same as for height) but failed. Need your valuable advise and ideas. Many Thanks.

Where did you creating subview?
Try to do it in -layoutSubviews method.
- (void)layoutSubviews {
[super layoutSubviews];
UIView* cellView = [[UIView alloc] initWithFrame:self.contentView.frame];
cellView.backgroundColor = [UIColor grayColor];
[self.contentView addSubview:cellView];
}
All frames for subviews are already calculated inside this method and you should receive correct width\height for your subview.

Can you try setting clip to bounds
[cellView setClipsToBounds:YES];

Related

Programmatically custom UITableViewCell using initWithStyle

I have created a few labels on my tableview using custom UITableViewCell and interface builder. Now i am using some third party control called BEMLineGraph and i want to add it to my tableview cell using code. It also has a few delegates and data source methods. I am doing the following but the problem is that i get duplicate graphs and messed up data upon scrolling up and down.
ProductsTableViewCell.m
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.productGraph = [[BEMSimpleLineGraphView alloc] initWithFrame:self.graphContainter.frame];
//_myGraph.enableTouchReport = YES;
self.productGraph.tag = 100;
self.productGraph.animationGraphStyle = BEMLineAnimationNone;
//_myGraph.enablePopUpReport = YES;
self.productGraph.enableXAxisLabel = YES;
self.productGraph.colorTouchInputLine = [UIColor whiteColor];
self.productGraph.colorXaxisLabel = [UIColor darkGrayColor];
self.productGraph.colorTop = [UIColor clearColor];
self.productGraph.colorBottom = [UIColor clearColor];
self.productGraph.colorLine = [UIColor colorWithRed:255.0/255.0 green:255.0/102.0 blue:255.0/102.0 alpha:1];
self.productGraph.colorPoint = [UIColor lightGrayColor];
[self addSubview:self.productGraph];
}
return self;
}
TableViewController.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
ProductsTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell = [cell initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.productGraph.frame = CGRectMake(0, 0, cell.graphContainter.frame.size.width, cell.graphContainter.frame.size.height);
cell.productGraph.dataSource = self;
cell.productGraph.delegate = self;
//All the other stuff is set here and works well.
}
- (NSInteger)numberOfPointsInLineGraph:(BEMSimpleLineGraphView *)graph
{
if (graph.tag == 100)
{
return productDetail.count;
}
else
{
return numbers.count;
}
one thing wrong I can see your code:
if (cell == nil)
{
cell = [cell initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
it should be:
if (cell == nil)
{
cell = [[ProductsTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
but this won't fix the problem of duplicate graphs
As you have subclassed the cell anyways, why don't you keep the delegate and datasource of the productGraph in the cell itself
If you have registered the ProductsTableViewCell class with the UITableView, then dequeueReusableCellWithIdentifier: will create an object of that class for you, and call its initWithCoder: method (for cells defined in Interface Builder). Therefore, remove the call to your initWithStyle:reuseIdentifier: and do initialisation in the initWithCoder: method of ProductsTableViewCell instead.
Then, in your cellForRowAtIndexPath: do only that what is specific for that cell. What that is depends on the implementation of your Graph class, but it needs to make sure that the old graph is not visible anymore.

Subclassing UIView with IBOutlets

I've been trying for a long time to add IBOutlets to a UIView.
Well, it seems impossible.
I created a class called "RecessCell".
The file's owner's class is "RecessCell" and the view object's class is RecessCell.
I created an outlet called "betweenPeriods" and everything seems to work.
Then, I tried to show the custom view in a UIScrollView inside a UITableViewCell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
RecessCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Recess"];
if(cell == nil) cell = (RecessCell *)[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Recess"];
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 1, 320, 50)];
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.bounces = NO;
scrollView.pagingEnabled = YES;
scrollView.contentSize = CGSizeMake(640, 50);
[scrollView addSubview:[[[NSBundle mainBundle] loadNibNamed:#"RecessCell" owner:self options:nil] objectAtIndex:0]];
[cell addSubview:scrollView];
return (UITableViewCell *)cell;
}
Of course, it didn't work. Every time I load the xib I get the annoying run-time error, that again and again makes me want to kill myself :
'[ setValue:forUndefinedKey:]: this class is
not key value coding-compliant for the key betweenPeriods.'
While SetupRecess is the UIViewController class.
SetupRecess shouldn't have an outlet for betweenPeriods - RecessCell should.
That's why I tried to change the owner in the loadNib method to cell.
Well, guess what? DIDNT WORK.
'[ setValue:forUndefinedKey:]: this class
is not key value coding-compliant for the key betweenPeriods.'
I'm totally frustrated, as you can see. I really have no idea what's the problem, and obviously not how to fix it.
Please help,
thank you.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
RecessCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Recess"];
if(cell == nil) {
NSArray *nib=[[NSBundle mainBundle] loadNibNamed:#"RecessCell" owner:self options:nil];
cell=[nib objectAtIndex:0];
cell.showsReorderControl=NO;
cell.selectionStyle=UITableViewCellSelectionStyleNone;
cell.backgroundColor=[UIColor clearColor];
}
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 1, 320, 50)];
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.bounces = NO;
scrollView.pagingEnabled = YES;
scrollView.contentSize = CGSizeMake(640, 50);
[scrollView addSubview:[[[NSBundle mainBundle] loadNibNamed:#"RecessCell" owner:self options:nil] objectAtIndex:0]];
[cell addSubview:scrollView];
return cell;
}

Background of View inside UITableView which is inside UITableViewCell

I have a UITableView inside UITableViewCell. The inner tableview is of size 5 with each cell contentview of different background color and is editable.I'm able to reorder the tableviewcells of inner tableview.
I have a custom backgroundview for outer UITableViewCell.
UIView *selectedBackgroundView = [[UIView alloc] init];
selectedBackgroundView.layer.borderColor = [[UIColor grayColor] CGColor];
selectedBackgroundView.layer.borderWidth = 1;
selectedBackgroundView.backgroundColor = [UIColor clearColor];
cell.selectedBackgroundView = selectedBackgroundView;
When I select the tableviewcell, the bg color of tableviewcells of inner tableview changes to white.
//CellForRow code of Parent TableView
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
TableViewCellCustom *cell = (TableViewCellCustom *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"TableViewCellCustom" owner:self options:nil];
cell = _tableViewCellCustom;
UIView *selectedBackgroundView = [[UIView alloc] init];
selectedBackgroundView.layer.borderColor = [[UIColor grayColor] CGColor];
selectedBackgroundView.layer.borderWidth = 1;
selectedBackgroundView.backgroundColor = [UIColor clearColor];
cell.selectedBackgroundView = selectedBackgroundView;
}
CustomPosition *customPosition = [_filteredArray objectAtIndex:indexPath.row];
[cell setProductsArray: customPosition.productsArray];//Sets the products and reloads child tableview
return cell;
}
//CellForRow of Child Tableview
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
TableViewCellProduct *cell = (TableViewCellProduct *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"TableViewCellProduct" owner:self options:nil];
cell = _tableViewCellProduct;
cell.viewProduct.transform = CGAffineTransformRotate(cell.viewProduct.transform, M_PI_2);
}
switch (indexPath.row) {
case 0:
cell.viewProduct.backgroundColor = [UIColor redColor];
break;
case 1:
cell.viewProduct.backgroundColor = [UIColor greenColor];
break;
case 2:
cell.viewProduct.backgroundColor = [UIColor blueColor];
break;
case 3:
cell.viewProduct.backgroundColor = [UIColor yellowColor];
break;
case 4:
cell.viewProduct.backgroundColor = [UIColor grayColor];
break;
default:
break;
}
Product *product = [_productsArray objectAtIndex:indexPath.row];
cell.lblProductName.text = product.name;
return cell;
}
Child tableview is rotated because i wanted horizontal tableview.
Anyone knows what is the solution for this?
When a table view cell is selected the framework goes through all subviews and changes thier background colour to UIColor clearColor. This is so that the background colour of the table view cell can be seen properly. Usually this is what you want.
If it isn't what you want, you need to subclass UITableViewCell so that, after selection, you can restore the background colour of all of the subviews. Or manage the result of the selection entirely yourself.

Crash after attempting to get a UIImageView reference through viewWithTag

I need to draw an image in a table cell. So far I have not been able to get a proper reference to the UIImageView after I create the view and assign it to the cell. The same procedure does work for a UILabel, for example.
I can't figure out what I'm doing wrong.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UIImageView *imageView;
UILabel *title;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
// Setup title
title = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 30)] autorelease];
title.tag = 1;
[cell.contentView addSubview:title];
// Setup image
UIImageView* imageView = [[[ UIImageView alloc] initWithFrame:
CGRectMake(50, 0, 50, 50)] autorelease];
imageView.tag = 2;
[cell.contentView addSubview:imageView];
} else {
// Get references to cell views
title = (UILabel *)[cell.contentView viewWithTag:1];
imageView = (UIImageView *)[cell.contentView viewWithTag:2];
}
NSLog(#"%#", [title class]); // UILabel
NSLog(#"%#", [imageView class]); // CRASH! EXC_BAD_ACCESS
return cell;
}
The problem is the scope of the imageView variables. In the case that the cell doesn't exist yet, you create a new UIImageView that only exists in the if-block. It hides the variable that you declared earlier and disappears after the if-block ends.
Instead of
UIImageView *imageView = ...
you should simply write
imageView = ...
Otherwise you're creating a new object that has nothing to do with the object you declared at the top of the method and the original imageView is still undefined.

UITableViewCell backgroundView image resizing?

I am using an image to display the whole content of a UITableViewCell and it's set using the backgroundView property.
My problem is that it is always scaled to fit the cell. Is there a way to disable scaling in this case, so I can provide the 480 pixel version only and it just gets cropped when orientation is portrait?
I'm doing it like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
UIImageView *bgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:#"menu.0%d.large.png", indexPath.row+1]]];
UIImageView *selectedBgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:#"menu.0%d.large.selected.png", indexPath.row+1]]];
cell.backgroundView = bgView;
cell.selectedBackgroundView = selectedBgView;
[bgView release];
[selectedBgView release];
return cell;
}
I tried using two versions of the images to switch between them when orientation is changed. This works so far, too, but it's got the drawback that you always see the scaling while the animation is processed.
Thanks for your help
Arne
Set the content mode of your background image views.
bgView.contentMode = UIViewContentModeTopLeft;
selectedBgView.contentMode = UIViewContentModeTopLeft;
This tells the UIImageView to put its image in the top left corner rather than scale it to fit.
I did not try this on the simulator or device, but the following might work:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// New!
cell.backgroundView.clipsToBounds = YES;
UIImageView *bgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:#"menu.0%d.large.png", indexPath.row+1]]];
UIImageView *selectedBgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:#"menu.0%d.large.selected.png", indexPath.row+1]]];
// New!
bgView.center = CGPointMake(160, 25); // Adjust the y-Value to be exactly half of the height of your cell
bgView.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin; // Not quite sure whether these two will work, maybe you have to play a little with the Masks
cell.backgroundView = bgView;
cell.selectedBackgroundView = selectedBgView;
[bgView release];
[selectedBgView release];
return cell;
}
Let me know whether you managed to get it running.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
is was you looking for, I think.
more information :
http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableViewDelegate_Protocol/Reference/Reference.html