UITableViewCell width is greater than UITableView width - objective-c

I encountered a weird problem. I am creating a custom selected view for my tableviews. However, this selection view doesn't fit well. I found out that this is because my selection view is 300px while the cell itself is 320px. The weird part is that the UITableView's width is actually just 300px only. How will I adjust the cell width of my table?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *tableIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:tableIdentifier];
if (cell == nil)
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:tableIdentifier] autorelease];
if (tableView == bandTable)
{
UIImageView *imageBg = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"column1_selected.png"]];
[imageBg setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
[tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
[cell setSelectionStyle:UITableViewCellSelectionStyleGray];
[cell setSelectedBackgroundView:imageBg];
[imageBg release];
NSArray *array = [bandDictionary objectForKey:#"Bands"];
cell.textLabel.text = [array objectAtIndex:indexPath.row];
NSLog(#"CELL: %f", cell.bounds.size.width);
}
return cell;
}

Just set
cell.frame = CGRectMake(0,
0,
self.tableView.frame.size.width,
cell.frame.size.height);
in cellForRowAtIndexPath.

Add this two lines after your cell gets created,
[[cell contentView] setFrame:[cell bounds]];
[[cell contentView] setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];

#IvorPrebeg, you shouldn't set the frame for the UITableViewCell inside cellForRowAtIndexPath. The UITableViewCell will automatically be set to the width of the UITableView after the cell did execute layoutSubviews. This will be done automatically after setting a value on the label you inserted in the cell.
Its just important to calculate inside heightForRowAtIndexPath a size based on the font and the text inserted into the cell which is equal to the one inside your cell. In my case it looks like this:
- (CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath{+
ChatMessage *message =
[self.fetchedResultsController objectAtIndexPath:indexPath];
CGSize size = [message.text sizeWithFont:self.messageCell.labelMessage.font
constrainedToSize:CGSizeMake(self.tableView.frame.size.width * 0.8f, HUGE_VAL)
lineBreakMode:NSLineBreakByWordWrapping];
return size.height;
}
And than inside the UITableViewCell:
- (void)layoutSubviews{
[super layoutSubviews];
if( _fInitWidth == 0 ){
self.labelMessage.preferredMaxLayoutWidth =
self.bounds.size.width * 0.8f;
}
[self.contentView setNeedsDisplay];
}
Like you can see, the prefferedMaxLayoutWidth of the UILabel inside my UITableViewCell will be 0.8 of the cells width (320 * 0.8). LayoutSubviews will be excecuted inside cellForRowAtIndex after setting up the cells properties. After that, UITableView will call the heightForRowAtIndexPath and calculate the size for the height. Therefore I calculate the UILabels size by passing a width * 0.8 for constrainedToSize ( tableview width is 320.0 * 0.8 ) the same as in the cell.
The example values are for iPhone devices, they will change on bigger screens of course.

On C#:
public UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath){
UITableViewCell cell = new UITableViewCell();
cell.Frame = new CoreGraphics.CGRect(0, 0,this.selectSchoolTableview.Frame.Width, cell.Frame.Size.Height);
cell.ContentView.AutosizesSubviews = true;
return cell;
}
Another trick:
public UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath){
UITableViewCell cell = new UITableViewCell();
cell.Accessory = UITableViewCellAccessory.None;
cell.ContentView.AutoresizingMask = UIViewAutoresizing.FlexibleWidth;
cell.ContentView.AutoresizingMask = UIViewAutoresizing.FlexibleHeight;
return cell;
}

Related

UITableView Cell highlight / retain selected value IOS

I have UIView(LeftMenu) with UITableView (UITableViewStylePlain). I have around 7 controllers , Where on selection of each cell I wanna push corresponding controller. I tried custom highlight for cell with yellow color as below ,
UIColor *yel=[[UIColor alloc]initWithRed:240/255.0 green:197/255.0 blue:67/255.0 alpha:1.0];
UIView *bgColorView = [[UIView alloc] init];
[bgColorView setBackgroundColor:yel];
[cell setSelectedBackgroundView:bgColorView];
in cellForRowAtIndexPath. But I am unable to retain selected cell If I move to next controller. In didSelectRowAtIndexPath , I am capturing last selected index ( When I select new cell , old should be unhighlighted). But it seems , If I make custom its not retaining. If I keep UITableViewCellSelectionStyleNone , cell.backgroundColor it works. But not highlighting :(
[[NSUserDefaults standardUserDefaults]setInteger:indexPath.row forKey:#"SSLastSelectedLeftMenuIndex"];
I am initializing UIView(LeftMenu) with frame.
Issue : Gray Color on Highlight after few mins custom yellow highlight coming and Not retaining selected cell color.
I know I am missing some silly thing. But its eating my time. Advance thanks :)
Update:-
below is my -cellForRowAtIndexpath method
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
if([[NSUserDefaults standardUserDefaults]integerForKey:#"SSLastSelectedLeftMenuIndex"]==indexPath.ro‌w)
{
///<HIGHLIGHT CODE>;
}
to select the last selectd cell .. (try)
- (void)viewWillAppear
{
[uper viewWillAppear];
//hear u can set the selected cell
//get indexpath of row
int k = your saved row
NSIndexPAth *path = [NSIndexPath indexPathWithIndex:k];//if u hav single section or u can use other class method
[tableView selectRowAtIndexPath:_selctedIndex animated:NO scrollPosition: UITableViewScrollPositionNone];//hear u are directly setting the last selected cell once view will appear
}
hop this helps u :)
if u are using UITableViewCell then u do something like this,for yellow color for selecting the cell
//in controller do like this
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if(cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
UIColor *yel=[[UIColor alloc]initWithRed:240/255.0 green:197/255.0 blue:67/255.0 alpha:1.0];
UIView *bgColorView = [[UIView alloc] init];
[bgColorView setBackgroundColor:yel];
[cell setSelectedBackgroundView:bgColorView];
}
return cell;
}
in the subclassed table cell there is one method, to display yellow color for selecting the cell
//in CustomCell.m
//in the custom cell set the color for selected state
//override this method
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
if(selected)
{
//same code of urs
UIColor *yel=[[UIColor alloc]initWithRed:240/255.0 green:197/255.0 blue:67/255.0 alpha:1.0];
UIView *bgColorView = [[UIView alloc] initWithFrame:self.bounds];//for entaire cell,set the frame
[bgColorView setBackgroundColor:yel];
[self setSelectedBackgroundView:bgColorView];
}
}
You have misunderstood selection and highlighting a cell you should change your cellForRowAtIndexPath like below to select the previously selected item.
before that Declare a globle variable _selctedIndex of type NSIndexpath to store the last selected cell
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
UIColor *yel=[[UIColor alloc]initWithRed:240/255.0 green:197/255.0 blue:67/255.0 alpha:1.0];
UIView *bgColorView = [[UIView alloc] init];
[bgColorView setBackgroundColor:yel];
[cell setSelectedBackgroundView:bgColorView];
}
if([[NSUserDefaults standardUserDefaults]integerForKey:#"SSLastSelectedLeftMenuIndex"]==indexPath.row)
{
//<HIGHLIGHT CODE>;
_selctedIndex=indexPath; //code Updated
}
return cell;
}
After your tableView has reloaded call the below line of code
[tableView selectRowAtIndexPath:_selctedIndex animated:NO scrollPosition:UITableViewScrollPositionTop];
}
The UITableViewCell class will assign the view you have mentioned to the property selectedBackgroundView instead of the Default blue color view for showing in the background when a cell is selected
I ran into the exact same problem in a project, when tapping on a cell long enough to engage highlight then moving to a scroll the UITableView holds onto the highlighted index somehow so that the next attempt to select uses that previous indexPath.
To resolve I did the following
Add Property to Track Offending indexPath
...
#property (nonatomic,strong) NSIndexPath *cachedPath;
...
Track indexPath with didUnhighlightRowAtIndexPath
- (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
self.cachedPath = indexPath;
}
On Drag reload offending indexPath
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
if (self.cachedPath)
{
[self.tableView reloadRowsAtIndexPaths:#[self.cachedPath] withRowAnimation:UITableViewRowAnimationNone];
}
self.cachedPath = nil;
}
For good measure clear the property on selection
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.cachedPath = nil;
}

can not set title for cell at specific indexPath.row of uicollectionview, UICollectionView

When working on UICollectionView, I am loading a cell from nib like below
- (void)viewDidLoad
{
[super viewDidLoad];
/* Uncomment this block to use nib-based cells */
UINib *cellNib = [UINib nibWithNibName:#"NibCell" bundle:nil];
[self.collectionView registerNib:cellNib forCellWithReuseIdentifier:#"cvCell"];
// Configure layout
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
self.collectionView.contentInset = UIEdgeInsetsMake(10.0f, 0.0f, 10.0f, 0.0f);
[flowLayout setItemSize:CGSizeMake(300, 200)];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
[self.collectionView setCollectionViewLayout:flowLayout];
}
And my nib file looks like below
The top label is used to displayed the number of cell and the middle label is used to display a certain text
in method cellForItemAtIndexPath, I just want to set the text to the cell of certain row ( in this example, I am doing it at row of 1 ) :
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
// Setup cell identifier
static NSString *cellIdentifier = #"cvCell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
UILabel *titleLabel = (UILabel *)[cell viewWithTag:100];
UILabel *cellLablel = (UILabel *)[cell viewWithTag:200];
cellLablel.text = self.dataArray[0][indexPath.row];
if ( indexPath.row == 1)
[titleLabel setText:#"this is row 1"];
return cell;
}
When running the app, there is a problem on it. Not only is titleLabel of cell at row1
set to This is row 1, but also the titleLabel of row5 and row9 and row10 is set as well:
If anybody knows what I am doing wrong in the middle. please help.
My colleciton is containing 1 section and 15 row for this section.
Cells are reused. As soon as you scroll down and Cell 1 gets invisible, the collection view makes it available again. Just set the text for all cells, e.g.
titleLabel.text = [NSString stringWithFormat:#"this is row %d", indexPath.row];

iOS tableview cell handling

I have this code, where "lineaRedToday" is an UIImageView:
- (void)viewDidLoad {
[super viewDidLoad];
lineaRedToday = [UIImage imageNamed:#"line4.png"];}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier";
MyIdentifier = #"tblCellView";
TableViewCell *cell = (TableViewCell*)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if(cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"TableViewCell" owner:self options:nil];
cell = tblCell;
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
[[lineDay objectAtIndex:currentTodaylineRed -1] setImage:lineaRedToday];
return cell;
- (IBAction) change{
lineaRedToday = [UIImage imageNamed:#"linea.png"];
[lineDay setImage:lineaRedToday];
[myTableView reloadData];
}
It is a UITableView with 15 custom UITableViewCell and I want to change the image at an UIImageView, this ImageView is "lineDay", lineDay is present in all cells, and I want change its image at all cells, but the IBAction "change" change the UIImageView only in the last cell and not at all....why?
yes it will change the image in last cell because it has the reference of only last cell, if you want to do this then when you are creating cell in cellForRowAtIndexPath check for a BOOL and set image according that BOOL. Also in IBAction change that BOOL value and call reloadData on table view to reload it. As -
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Test";
UITableViewCell *cellView = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cellView == nil)
{
cellView = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
UIImageView *bgImgView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 85.0f)];
[bgImgView setTag:1];
[bgImgView setBackgroundColor:[UIColor clearColor]];
[cellView.contentView addSubview:bgImgView];
[bgImgView release];
}
UIImageView *imgView = (UIImageView*)[cellView viewWithTag:1];
if (buttonPressed)
{
[imgView setImage:[UIImage imageNamed:#"listing_bg"]];
}
else
{
[imgView setImage:[UIImage imageNamed:#"featured_listing_bg"]];
}
return cellView;
}
- (IBAction) change{
buttonPressed = !buttonPressed;
[myTableView reloadData];
}
First, lineaRedToday is an UIImage, not an UIImageView. The first is an image, the second an object in the view hierarchy.
Then, in your code
if(cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"TableViewCell" owner:self options:nil];
cell = tblCell;
}
you use tblCell. I cannot see what this is. You should assign something from what you were just loading from the nib.
I don't know what lineDay is exactly, but a single view (i.e. UIImageView) can only be present in one cell, not in many. If you change the image (lineaRedToday), you still have to set this new image in your views. There should be something like
cell.yourImageView.image = linaRedToday;
when configuring the cell.

Animating a font size change in a UITableView

Hey Simple little app for educational purposes, its a simple uitableview and I want users to be able to use a uislider to adjust the font size as needed. The code I have now works to change the font but only when the view is updated, ie when i pull up or down the table view to reveal other cells. I'd like the font change to be reflected immediately as a user moves the uislider if possible, here's the code that I have working half way:
-(UITableViewCell *) tableView: (UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *) indexPath {
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
if (cell == nil)
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier: SimpleTableIdentifier] autorelease];
NSUInteger row = [indexPath row];
cell.text = [listData objectAtIndex:row];
UIImage *image = [UIImage imageNamed:#"star.png"];
cell.font = [UIFont systemFontOfSize:[fontSlider value]];
cell.image = image;
return cell;
}
You could make an IBAction for the fontSlider for the "Value Changed" option as follows:
-(IBAction) refreshResize
{
[self.view setNeedsDisplay];
}
That should work. setNeedsDisplay refreshes the screen.

How to change the height of table view cell

i m trying to read some RSS data. I have the data that is of different sizes. the data is present in tabke view data object. I used the label to add the data and resize the dat. No success. Please help.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
NSLog(#"in the tabel view cell");
heightOfCell=[self tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Default"];
if (cell == nil)
{
//cell = [[[UITableViewCell alloc] initWithFrame:CGRectMake(55.0,42.0,245.0,heightOfCell) reuseIdentifier:#"Default"] autorelease];
UILabel *label = [[UILabel alloc] init];
NSString *cellText = [[TableViewData news] valueForKey:[NSString stringWithFormat:#"%d",[indexPath row]]];
UIFont *cellFont = [UIFont fontWithName:#"Helvetica" size:10.0];
CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);
label.text = [[TableViewData news] valueForKey:[NSString stringWithFormat:#"%d",[indexPath row]]];
CGSize labelSize = [[[TableViewData news] valueForKey:[NSString stringWithFormat:#"%d",[indexPath row]]] sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
label.lineBreakMode=UILineBreakModeWordWrap;
[label sizeThatFits:labelSize];
cell = [[[UITableViewCell alloc] initWithFrame:CGRectMake(55.0,42.0,245.0,heightOfCell) reuseIdentifier:#"Default"] autorelease];
//[label sizeToFit];
[cell addSubview:label];
[label release];
}
}
you need to use the following method.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 45;
}
you need to change the height as per your requirements
It should be noted that the default height is 44.
You need to implement the following method:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// some code that compute row's height
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 50;
// This is just Programatic method you can also do that by xib !
}
You can also change it in Interface Builder. Open the *.xib file, select the table, show the Size Inspector, and change the row height. But, please note that the default height is 44 pixels.
There are two methods to set the UITableViewCell's height .:
UITableView has a property named rowHeight, with which you can use to set all the UITableViewCell to the same row height;
If you implement the UITableViewDelegate protocol , and include tableView:heightForRowAtIndexPath: method, it's you responsbility to decide the current UITableViewCell'height. In practice, we always use the delegate method to set the cell's height, only if each cell's height may be dynamic! And the method is preference to the UITableView's rowHeight property!
So, I think you may prefer the second method:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *cellText = [[TableViewData news] valueForKey:[NSString stringWithFormat:#"%d",[indexPath row]]];
UIFont *cellFont = [UIFont fontWithName:#"Helvetica" size:10.0];
CGSize labelSize = [cellText sizeWithFont:cellFont
constrainedToSize:constraintSize
lineBreakMode:UILineBreakModeWordWrap];
return lableSize ;
}
I saw a lot of solutions but all was wrong or uncomplet. You no need calculate nothing (no font, no size, nothing)...
You can solve all problems with 5 lines in viewDidLoad and autolayout.
This for objetive C:
_tableView.delegate = self;
_tableView.dataSource = self;
self.tableView.estimatedRowHeight = 80;//the estimatedRowHeight but if is more this autoincremented with autolayout
self.tableView.rowHeight = UITableViewAutomaticDimension;
[self.tableView setNeedsLayout];
[self.tableView layoutIfNeeded];
self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0) ;
For swift 2.0:
self.tableView.estimatedRowHeight = 80
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.setNeedsLayout()
self.tableView.layoutIfNeeded()
self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0)
Now create your cell with xib or into tableview in your Storyboard
With this you no need implement nothing more or override. (Don forget number os lines 0) and the bottom label (constrain) downgrade "Content Hugging Priority -- Vertical to 250"
You can donwload the code in the next url:
https://github.com/jposes22/exampleTableCellCustomHeight
References: http://candycode.io/automatically-resizing-uitableviewcells-with-dynamic-text-height-using-auto-layout/
You have to know the heights of all cells before the tableView:cellForRowAtIndexPath: delegate call which may require you to store heights inside your view controller or some other list.
The function to customise the heights of cells is tableView:heightForRowAtIndexPath:. The default height for a table view is 44 pixels, for reference.
You can find the documentation here.