Change UIView Position in TableView Cell - ios

I have UIView in my tableview custom cell, when it appears i want to change the position of the the UIView based on certain condition.
i put this code in method cellForRowAtIndexPath:
CGRect newFrame = CGRectMake(11, 306, 302, 95);
[cell.myView setFrame:newFrame];
[cell setNeedsLayout];
I'm certain that the view already have the new position based on NSLog.
But it still in the same position in my screen.
Is there any steps that I missed?

The frame you are assigning based on certain condition, needs to be assigned inside LayoutSubviews method of UITableViewCell Class.

Related

UITableViewCell not responding to setNeedsLayout

I have a UITableView in Grouped format with a few cells in it. In the cells is a UIView to which I am adding another UIView. When I update the frame of the first UIView, it doesn't change the position of it nor the size.
The UIViews realign themselves correctly if the cell goes offscreen and onscreen again, so the actual transformation is being applied, it's just the re-rendering that's not happening properly.
The code for this is just in my cellForRowAtIndexPath:
[cell.cellMoney setBackgroundColor:[UIColor clearColor]];
[cell.cellMoney.subviews makeObjectsPerformSelector:#selector(removeFromSuperview)];
UIView *sellMoneySubView = [UIMoneyDisplay createViewWithAmount:item.min_sale_unit_price fontSize:17.0];
[cell.cellMoney setFrame:CGRectMake(cell.frame.size.width-sellMoneySubView.frame.size.width-20, 7, sellMoneySubView.frame.size.width, sellMoneySubView.frame.size.height)];
[cell.cellMoney addSubview:sellMoneySubView];
[cell setNeedsLayout];
The sub UIView that I'm adding to the first UIView gets added and rendered properly, it's just the first's positioning that's gone weird.
Oh, I'm also using AutoLayout with the storyboard.
Addition: I fixed part of my problem, but the title is still valid. I also have a cell with an image that needs to be downloaded through the network, but that cell doesn't respond to any form of layout call either.
I fixed the problem with the position of the UIView by removing the middle view and adding straight to the cell's contentView.
instead of this
[cell setNeedsLayout]
use [cell layoutIfNeeded]
[cell.cellMoney setBackgroundColor:[UIColor clearColor]];
[cell.cellMoney.subviews makeObjectsPerformSelector:#selector(removeFromSuperview)];
UIView *sellMoneySubView = [UIMoneyDisplay createViewWithAmount:item.min_sale_unit_price fontSize:17.0];
[cell.cellMoney setFrame:CGRectMake(cell.frame.size.width-sellMoneySubView.frame.size.width-20, 7, sellMoneySubView.frame.size.width, sellMoneySubView.frame.size.height)];
[cell.cellMoney addSubview:sellMoneySubView];
[cell layoutIfNeeded]; //use this
return cell;
This might helps you :)

Separator insets not working

I have a UITableView in a Storyboard where I have configured the Separator Inset to custom (0,0) as well as for the Prototype Cell (0,0).
While I can see the separator line is now 100% the width of the table, the UIImageView (subclassed to AsyncImageView) is still positioned to the right by 15px.
I've tried setting it on the table view on load and when the cell is constructed from a dequeue but I'm still seeing a padding on the left. (I've queried the cell and table and the inset and frame has zero left padding).
Is there anything I'm missing?
You have to subclass UITableViewCell and call layoutSubviews from your newly created UITableViewCell class, in the layoutSubviews method, use
- (void)layoutSubviews{
[super layoutSubviews];
self.imageView.frame = CGRectMake(0, 0, 50, 50); // override frame of your choice
}

what's wrong with this assign?

I am using GMGridView in my project. And in - (GMGridViewCell *)GMGridView:(GMGridView *)gridView cellForItemAtIndex:(NSInteger)index method, i write a snippet which is out of my expectation. The snippet is as follows:
if (!cell)
{
cell = [[GMGridViewCell alloc] init];
ThumbImageView *view = [[ThumbImageView alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];
[view setBackgroundColor:DEFAULT_BACKGROUND_COLOR];
[view setImage:[UIImage imageWithContentsOfFile:path]];
view.userInteractionEnabled = YES;
view.layer.shadowOffset = CGSizeMake(8, 8);
view.layer.shadowOpacity = 0.5;
NSLog(#"view frame width:%f,height:%f",view.frame.size.width,view.frame.size.height);
cell.contentView = view;
NSLog(#"cell.contentView frame width:%f,height:%f",cell.contentView.frame.size.width,cell.contentView.frame.size.height);
}
when it runs the output is as follows:
2013-06-03 11:02:05.508 XXX[71692:707] view frame width:115.000000,height:180.000000
2013-06-03 11:02:05.511 XXX[71692:707] cell.contentView frame width:0.000000,height:0.000000
why assign view to cell.contentView, cell.contentView.frame.size still be zero? and also cell.contentView can display the image properly. what's the reason? I am totally confused:(.
Check the docs:
contentView
Returns the content view of the cell object. (read-only)
#property(nonatomic, readonly, retain) UIView *contentView
contentView is a readonly property. You can't assign it.
The problem is probably that you've created new views, and you're looking at the frame of one of those views before the run loop has reached its layout phase.
When you create the GMGridViewCell, it starts with a default frame and bounds of CGRectZero. When you set its content view, it sets the content view's frame to its (the cell's) bounds. So even though you set the content view's frame directly using initWithFrame:, the frame gets changed to CGRectZero when you set the view as the cell's content view.
Since the cell isn't a subview of the grid view yet, there's no way to ask the grid view to lay out the cell by the time you're trying to log the content view's frame. If the grid view is using a constant size for all cells, and you know what that size is, you could manually set the cell to that size before setting the cell's content view. Otherwise, you need to wait until after the grid view's layoutSubviews method has run to check the content view's frame.

Table Cell TextLabel frame width increasing automatically

I wish to have a table with some label and then I add a text field UI after the label.
I want the Label to be of some fixed size (say 150) and the rest of the cell width be occupied by the textfield.
Hence I set the frame of my cell.textLabel in function
cellForRowAtIndexPath
in this way
[cell.textLabel setFrame:CGRectMake(cell.textLabel.frame.origin.x, cell.textLabel.frame.origin.y, 150, cell.textLabel.frame.size.height)];
but this doesnt seem to work.
Any ideas why and What could be my solution to this?
why don't you add custom lable on your cell...
UILabel *mylabel = [[UILabel alloc] initWithFrame:CGRectMake(5,5, 150, 40)];
[cell.contentView addSubview:mylabel];
Otherwise you need to override -LayoutSubViews method and have to subclass UITableViewCell..
With a UITableViewCell its responsible for laying out its subviews. You have a very high level control over its layout using the UITableViewCellStyle enum.
If you want something custom, override UITableViewCell and add view to its content view or modify existing views. When you do this, be sure to do the layout in the layoutSubviews method, e.g.
- (void)layoutSubviews
{
[super layoutSubviews];
self.textLabel.frame = CGRectMake(self.textLabel.frame.origin.x,
self.textLabel.frame.origin.y,
150,
self.textLabel.frame.size.height);
}
The cell's frame will change when its added to the UITableView. When the cell's frame changes layoutSubviews is called to give you a chance to adjust its subviews. By default the UITableViewCell will do some if its own adjustments which is what was probably causing your issue.

UIView not resizing within UITableViewCell

I have a custom UITableViewCell that has two elements. A UIView and a UILabel. The cell is used for voting so I want to be able change the dimensions fo the UIView based on the vote. I currently am setting the frame of the UIView in the cellForIndexAtPath method. The frame of the UIView is being changed correcting (as I am checking in 3 places to make sure using NSLogs) but is not being reflected on the cell after they are displayed on the screen. Does anyone know why the UIView's frame would say it has changed but when displayed it would stay at the cell's frame size?
EDIT
NSLog(#"before: %#",NSStringFromCGRect(cell.voting_scale.frame));
[cell.voting_scale setFrame:CGRectMake(0.0, 0.0, width, row_dim.height+10.0)];
[cell.voting_scale setBounds:CGRectMake(0.0, 0.0, width, row_dim.height+10.0)];
[cell.voting_scale setClipsToBounds:true];
NSLog(#"after: %#",NSStringFromCGRect(cell.voting_scale.frame));
Hope this helps more
I don't have a thorough understanding of the behind-the-scenes processes of UITableView but I have found that when my UITableViewCell subclasses don't seem to be working as intended, that moving as much of the code as I can to the layoutSubviews method of the subclass instead of calling it in cellForRowAtIndexPath of the UITableViewController helps.

Resources