I'm having trouble with reducing the spacing between my cells, I want it to be 1 px. Inside my cell I have a stackView which fills my entire cell, both set to 70.
I can accomplish almost what I want by adding negative constrains, but then my cells gets too big, I only want it to be 70. I set the cell to 70 in the custom cell class
self.frame.size.height = 70
And my stackView is set to the very same. I don't see why I get that amount of spacing between my cells?
Please use the below method to adjust the cell height;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 78;
}
1) Between 2 cells of table view always has no space
2) You set self.frame.size.height = 70 in your custom cell. But it will be useless ! Try this datasource method
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
3) Please check the height of the white view
I have custom table view.I have added 4 views in that
1.ImageView
2.Three labels
Now I want that image should increase in size for multiple devices.For that i have given it below constraints.Proptional height is 176:339
Now in order to increase the height of the image i have increase height of table i used below code.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if(!self.customCell)
{
self.customCell = [self.tableview dequeueReusableCellWithIdentifier:#"tableCell"];
}
CGFloat height;
height=self.customCell.img_main.frame.size.height;
height=height+self.customCell.label_one.frame.size.height;
height=height+self.customCell.label_two.frame.size.height;
height=height+self.customCell.label_three.frame.size.height;
height=height+self.customCell.dev_name.frame.size.height;
NSLog(#"height is %f",self.customCell.img_main.frame.size.height);
return height;
}
The heigh of image is always 176 which i set in interface builder for 4 inch screen.
Why the height of both images & table view cell is not increasing ?
This is for your second question, if you want to change the image view's height base on the image it display, i suggest to use Height Constraint instead of Proportional Height Constraint, the calculation will be easier. When you get the image, and know the image size, so you calculate and get the size of the image view, and then update the Height Constrains. Done.
drag the constraint to your cell
update the constraint when image setted
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
CustomeCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CellId" forIndexPath:indexPath];
cell.image = image;
cell.imageViewHeightConstraint.constant = [self calcuteSizeWithImage:image]; //you need to do the calculation yourself
return cell;
}
I have a UITableView and there are 10 rows (This is a dynamic table, so more rows will be loaded).
Each cell/row should have the height of the full screen. There are different screen sizes in iOS now.
Therefore i am not able to give a fixed height for cell row as iOS devices have varying heights.
So how can I make a cell height to fit the screen height ?
If your tableView is in a ViewController then you can use this code below:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return CGRectGetHeight(self.view.bounds);
}
Else if your screen covers full screen, then use this
return CGRectGetHeight([[UIScreen mainScreen] bounds]);
Else if your screen contains a Navigation Bar as well, then use
return CGRectGetHeight([[UIScreen mainScreen] bounds] - 64.0f);
Or the Best Solution would be perhaps
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return CGRectGetHeight(tableView.bounds);
}
Edited
Its better to use rowHeight property instead of the delegate. Reason discussed below:
There are performance implications to using
tableView:heightForRowAtIndexPath: instead of rowHeight. Every
time a table view is displayed, it calls
tableView:heightForRowAtIndexPath: on the delegate for each of its
rows, which can result in a significant performance problem with table
views having a large number of rows (approximately 1000 or more).
Thanks to rdelmar
Source
How about this?
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return self.view.frame.size.height-yourTableViewStartingYPosition;
}
If it's full screen it will be return self.view.frame.size.height
I want to set a image for UITableviewcell but imageview contentmode is UIViewContentModeScaleAspectFit and also set full width depends on width height of UIIMageView is change,how to do that.
Change your UIIMageView content mode to UIViewContentModeScaleToFill or UIViewContentModeScaleAspectFill
Edited
Use following UITableView's Method
Add you UIImageView Height in NSMutableArray (heightsArray)
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [heightsArray objectAtIndex:indexpath.row];
}
SUMMARY
Given that we don't always know what the frame of a cell or its content view is going to be (due to editing, rotation, accessory views etc.), what is the best way to calculate the height in tableView:heightForRowAtIndexPath: when the cell contains a variable height text field or label?
One of my UITableViewController's contains the following presentation:
UITableViewCell with UITextView.
UITextView should be the same width and height as UITableViewCell.
I created the UITableViewCell subclass, and then and initialized it with UITextView (UITextView is a private field of my UITableViewController)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"TextViewCell";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[BTExpandableTextViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier textView:_notesTextView] autorelease];
}
return cell;
}
I implemented the following method in my UITableViewCell subclass:
- (void)layoutSubviews{
[super layoutSubviews];
CGFloat height = [textView.text sizeWithFont:textView.font constrainedToSize:CGSizeMake(textView.frame.size.width, MAXFLOAT)].height + textView.font.lineHeight;
textView.frame = CGRectMake(0, 0, self.contentView.frame.size.width, (height < textView.font.lineHeight * 4) ? textView.font.lineHeight * 4 : height);
[self.contentView addSubview:textView];
}
and of course i implemented the following UITableViewDataSource method (look! I am using self.view.frame.size.width (but really i need UITableViewCell contentView frame width):
- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath{
CGFloat height = [_notesTextView.text sizeWithFont:_notesTextView.font
constrainedToSize:CGSizeMake(self.view.frame.size.width, MAXFLOAT)].height;
CGFloat groupedCellCap = 20.0;
height += groupedCellCap;
if(height < [BTExpandableTextViewCell minimumTextViewHeightWithFont:_notesTextView.font]){
height = [BTExpandableTextViewCell minimumTextViewHeightWithFont:_notesTextView.font];
}
return height;
}
also I implemented the following method (thats not so important but ill post it anyway, just to explain that cell's height is dynamical, it will shrink or expand after changing text in UITextView)
- (void)textViewDidChange:(UITextView *)textView{
CGFloat height = [_notesTextView.text sizeWithFont:_notesTextView.font
constrainedToSize:CGSizeMake(_notesTextView.frame.size.width, MAXFLOAT)].height;
if(height > _notesTextView.frame.size.height){
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
}
And now, my question is:
After loading view, UITableViewController is calling methods in the following order: (ill remove some, like titleForHeaderInSection and etc for simplification)
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath{
and only then
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Look! I should return the correct UITableViewCell height before cellForRowAtIndexPath!
That means: I don't know UITableViewCell contentView frame. And i can't get it programmatically.
This width can be one of:
iPhone plain table, portrait orientation
iPhone plain table, landscape orientation
iPhone grouped table, portrait orientation
iPhone grouped table, landscape orientation
and the same for the iPad ( another 4 values )
And don't forget that contentView frame can be smaller because of UITableViewCell accessoryType, or because of UITableView editing state. (for example if we have UITableViewCell with multiline UILabel of any height in any editing state and with any accessoryView)
So this problem is fundamental: I just can't get cell contentView frame width for constraining, because I should return this height before cell layouts contentView. (And this is pretty logical, by the way) But this contentView frame really matters.
Of course sometimes I can know this width exactly and "hardcode" it
(for example: UITableViewCellAccessoryDisclosureIndicator has 20 px width, and tableView cannot be in editing state, then I can write self.view.frame.size.width - 20 and the task is done)!
Or sometimes contentView is equal to UITableViewController's view frame!
Sometimes I'm using self.view.frame.width in -tableView:heightForRowAtIndexPath: method.. (like now, and it works pretty well, but not perfectly because of grouped UITableView, should subtract some constant values, and they are different for 2 devices * 2 orientations)
Sometimes I have some #defined constants in UITableViewCell (if I know width exactly)...
Sometimes I'm using some dummy pre-allocated UITableViewCell (what is just stupid, but sometimes is pretty elegant and easy for use)...
But I don't like anything of that.
What's the best decision?
Maybe i should create some helper class, that will be initialized with such parameters:
accessory views, device orientation, device type, table view editing state, table view style (plain, grouped), controller view frame, and some other, that will include some constants (like grouped tableView offset, etc) and use it to find the expected UITableViewCell contentView width? ;)
Thanks
Table view uses the tableView:heightForRowAtIndexPath: method to determine its contentSize before creating any UITableViewCellcells. If you stop and think about it, this makes sense, as the very first thing you would do with a UIScrollView is set its contentSize. I have run into a similar problem before, and what I've found is that it is best to have a helper function that can take the content going into the UITableViewCell and predict the height of that UITableViewCell. So I think you will want to create some sort of data structure that stores the text in each UITableViewCell, an NSDictionary with NSIndexPaths as keys and the text as values would do nicely. That way, you can find the height of the text needed without referencing the UITableViewCell.
Although you can calculate heights for labels contained in table view cells, truly dynamically, in '- layoutSubviews' of a UITableViewCell subclass, there's no similar way of doing this (that I know of) for cell heights in '- tableView:heightForRowAtIndexPath:' of a table view delegate.
Consider this:
- (void)layoutSubviews
{
[super layoutSubviews];
CGSize size = [self.textLabel.text sizeWithFont:self.textLabel.font
constrainedToSize:CGSizeMake(self.textLabel.$width, CGFLOAT_MAX)
lineBreakMode:self.textLabel.lineBreakMode];
self.textLabel.$height = size.height;
}
Unfortunately though, by the time '- tableView:heightForRowAtIndexPath:' is called, that is too early, because cell.textLabel.frame is yet set to CGRectZero = {{0, 0}, {0, 0}}.
AFAIK you won't be able to do this neither with content view's frame, nor summing up individual labels' frames...
The only way I can think of is to come up with a convenience class, methods, constants, or such that will try to cover up all possible width in any device orientation, on any device:
#interface UITableView (Additions)
#property (nonatomic, readonly) CGFloat padding;
#end
#implementation UITableView (Additions)
- (CGFloat)padding
{
if (self.formStyle == PTFormViewStylePlain) {
return 0;
}
if (self.$width < 20.0) {
return self.$width - 10.0;
}
if (self.$width < 400.0 || [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return 10.0;
}
return MAX(31.0, MIN(45.0, self.$width * 0.06));
}
#end
Also note that, recently we also have new iPhone 5's 4-inch width (568 instead of 480) in landscape orientation.
This whole thing is pretty disturbing, I know... Cheers.