I have a UITableViewController that displays a custom UITableViewCell (inherited from UITableViewCell). That same UITableViewCell has a UILabel that can have text of variable length. The challenge I am having is how to access this UILabel in my UITableViewController so that I can set the correct cell height in heightForRowAtIndexPath.
Or on a side note how do I solve my problem of having a dynamicically sized label.
thanks
Here is my code for the custom UITableViewCell:
header:
#import <UIKit/UIKit.h>
#interface MessagesCustomViewCell : UITableViewCell
#property (nonatomic, weak) IBOutlet UILabel *message; <---- need to access this
#end
implementation:
#import "MessagesCustomViewCell.h"
#implementation MessagesCustomViewCell
#synthesize message=_message;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
#end
Using the way of measuring the font size mentioned by Ivan, you could additionally add a class metod to MessagesCustomViewCell,
+ (CGFloat)heightForMessage:(NSString *)message;
in which you calculate the height of message using the appropriate UILabel width/height, font etc. This could be called from heightForRowAtIndexPath: as such:
NSString *dynamicString = [self.mydata objectAtIndex:indexPath.row];
CGFloat height = [MessagesCustomViewCell heightForMessage:dynamicString];
return height;
Call [tableView reloadData] once data is updated.
Check the size with [yourString sizeWithFont:(UIFont*) forWidth(CGFloat) lineBreakMode:(NSLineBreakMode)] method in heightForRowAtIndex. The referred method will return a required size (including the height).
Related
So I have a custom UITableViewCell:
TestTableViewCell.h
#import <UIKit/UIKit.h>
#interface TestTableViewCell : UITableViewCell
#property (strong, nonatomic) IBOutlet UILabel *testCellLabel;
#end
TestTabelViewCell.m
#import "TestTableViewCell.h"
#implementation TestTableViewCell
-(id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
_testCellLabel = [[UILabel alloc] init];
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
#end
And then I have view controller with a table view that uses the custom table view cell. However this issue is that I don't want to use dequeueReusableCellWithIdentifier within the cellForRowAtIndexPath. I instead want to have an array of cells.
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
#end
ViewController.m
#import "ViewController.h"
#import "TestTableViewCell.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UITableView *tableView;
#property (strong, nonatomic) NSArray *myTableViewCells;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSArray *)myTableViewCells {
TestTableViewCell *cell1 = [[TestTableViewCell alloc] init];
cell1.testCellLabel.text = #"one";
cell1.backgroundColor = [UIColor blueColor];
TestTableViewCell *cell2 = [[TestTableViewCell alloc] init];
cell2.testCellLabel.text = #"two";
cell1.backgroundColor = [UIColor greenColor];
if (!_myTableViewCells) {
_myTableViewCells = #[cell1, cell2];
}
return _myTableViewCells;
}
#pragma mark - UITableView delegate functions
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.myTableViewCells.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TestTableViewCell *cell = self.myTableViewCells[indexPath.row];
return cell;
}
#end
The problem is that there is no testCellLabel appearing in the table view cell. I know the cells are there, because I set their background colour.
After talking to a few people, apparently I need to do some sort of loading from the XIB or the NIB for the UI to load properly? Even though the label is defined in the cell in the storyboard.
I know this is going against the norm and that Apple really wants you to use dequeueReusableCellWithIdentifier, but I know it won't work in the situation I need it in. I have done the reading on that much so please don't just tell me to use it. This code example is just very basic for example sake and ease of use.
Any help would be greatly appreciated.
TestTableViewCell *cell1 = [[TestTableViewCell alloc] init];
Creates a new TestTableViewCell object and does not instantiate it from the storyboard like you're thinking it does. Therefor all outlets created will be nil and simply not show up. The fact that you can set the background colour is not evidence that your implementation works.
You need to use dequeueReusableCellWithIdentifier. You say that it doesn't work for your problem.. show me how it doesn't work and I will tell you why you're wrong.
Edit
I see in your comments you say your cell needs a custom setter. Well, when you use dequeueReusableCellWithIdentifier you can do all setup work in awakeFromNib (If using a xib file) OR initWithCoder if you are using the storyboard.
You can create cell without dequeueResableCellWithIdentifer.
[[UITableViewCell alloc]initWithStyle:<#UITableCellStyle#> resueIdentifier:<#(nullable *NSString)#>]
I may be going about this wrong. So I have created a UITableView that essentially has a auto-layout trailing space set to the main view. I am creating a custom cell for this table so I drug on a prototype cell, customized it, and created my class for it. That is all working just fine.
What I can't seem to solve is the custom cell isn't going the full width of the actual table cell so a white background just shows up. If I don't use the custom cell the entire width table cell gets utilized.
I set the constraints for the cell content so that the background image should fill the cell.
What am I doing wrong? Let me know what you need to help solve this.
ProfileCustomCell.h
#import <UIKit/UIKit.h>
#interface ProfileCustomCell : UITableViewCell {
}
#property (nonatomic, strong) IBOutlet UILabel *nameLabel;
#property (nonatomic, strong) IBOutlet UIImageView *profileImageView;
#end
ProfileCustomCell.m
#import "ProfileCustomCell.h"
#implementation ProfileCustomCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.nameLabel.text = nil;
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
}
#end
UITableView
[tableView registerNib:[UINib nibWithNibName:#"ProfileCustomCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:#"Cell"];
[tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
ProfileCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
cell.nameLabel.text = [NSString stringWithFormat:#"%#", [child objectForKey:#"first_name"]];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
Can you post the code please .
Did you enable the Use Auto layout and Use Size Classes as below do that first in both table view and table view cell .and tell me your problem
1)After that select both image and label and do as below
2) Select the image and do below
3) select the label an do the following
Can you check the link below:
Table cell content(title) moving left after selecting cell
Instead of "filling", auto layout constraints to leading and trailing space to constant 0 and make sure they're not relative to margins.
select your table view cell's connection inspector and check if you haven't connected
editingAccessoryView by mistake
For those that are still having a similar issue and the above fixes are not working, make sure to set Estimated Size of the cell to None. This can be done in the Storyboard Size Inspector. Was stuck for much to long on this one!
I have an image property on my table view cell. I want to populate this image to an image.
My cell looks like:
//.h
#interface GAFriendStatusTableViewCell : PFTableViewCell
#property (weak, nonatomic) IBOutlet UIImageView *friendImage;
#end
//.m
#import "GAFriendStatusTableViewCell.h"
#implementation GAFriendStatusTableViewCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.friendImage.image = [UIImage imageNamed:#"user.png"];
}
return self;
}
- (void)awakeFromNib
{
// Initialization code
}
#end
This doesn't set the image. How can I set the image for this cell within the cell class?
Since your image view is an IBOutlet, I'm assuming you've got your cell layout defined in a .xib or storyboard. That being the case, your initialization code should go in the awakeFromNib method. This is the method that is called when the cell is created from the nib. That's why the //Initialization code comment is there. initWithStyle:reuseIdentifier: is never called in this scenario, which is why your image is not appearing.
Set it in - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
Otherwise if you have a Nib or Storyboard you're using then set the default in the prototype cell you are using.
I have a UITableView that covers the whole screen, with a lot of cells.
On the view that holds the UITableView I want to display an UIImage at the top right corner.
This UIImage (or UIImageView) is fixed on the UIView - it is not part of the tableView (in the z order it is over the tableView).
It is possible to let the UITableView float around this image, even when scrolling?
Below an image of my desired structure. Imagine that they are more cells even under der image. The cells (or UILabels) that are covered by the image should be truncated (or do a line break).
Is this possible? Currently I have no idea how to do this.
One option is to adjust the trailing space constraint of a label on your custom table view cell based on tableview's scrollview delegate method. You need to check if your cell is in the area of your imageView and then adjust the constraint. You also need to adjust the constraint in your cellForRowAtIndexPath for the initial layout.
Storyboard
ViewController.m
#import "ViewController.h"
#import "MyCell.h"
#interface ViewController () <UITableViewDataSource, UITableViewDelegate>
#property (weak, nonatomic) IBOutlet UITableView *tableView;
#property (weak, nonatomic) IBOutlet UIImageView *imageView;
#end
#implementation ViewController
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:#"MyCell" forIndexPath:indexPath];
// Configure the cell...
cell.myLabel.text = #"Lorem ipsum dolor sit amet, etc.";
if (indexPath.row >=3 && indexPath.row <= 5) {
cell.trailingSpaceConstraint.constant = 168;
}
return cell;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
NSUInteger count = 0;
for (MyCell *cell in [self.tableView visibleCells]) {
if (count >= 3 && count <= 6) {
cell.trailingSpaceConstraint.constant = 168.0;
} else {
cell.trailingSpaceConstraint.constant = 20.0;
}
count++;
}
}
#end
MyCell.h
#import <UIKit/UIKit.h>
#interface MyCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UILabel *myLabel;
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *trailingSpaceConstraint;
#end
Output
In this sample you need to use custom ViewController, add tableView and imageView, hook tableView's delegate and datasource and outlet. You also need to add custom subclass of UITableViewCell (MyCell) and hook outlets of the cell's label and the trailing space constraint.
The check at scrollViewDidScroll for rows is quick and dirty. Probably a better solution might be to check which cells are touching the imageView rect in indexPathsForRowsInRect.
I would like to set a custom cell so I created the CustomDetailCell class and a cell on the storyboard where I've created 2 UILabel. For the labels I change the font and the size and connect the custom class with the cell on the storyboard. I try to use it like this:
case DetailControllerAddressSection:
{
CustomDetailCell *customCell = (CustomDetailCell *)[tableView dequeueReusableCellWithIdentifier: #"AddressCell" forIndexPath: indexPath];
customCell.addresLabel.text = [self.objectData pointSubtitle];
customCell.distanceLabel.text = [self distanceMessageForObjectData: self.objectData];
return customCell;
break;
}
But on my cell there is only one label with the other font (not like in storyboard cell)
Can't understand this.. Any help?
PS The identifier for the cell is used in storyboard.
EDIT: Custom controller
#import <UIKit/UIKit.h>
#interface CustomDetailCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UILabel *addressLabel;
#property (weak, nonatomic) IBOutlet UILabel *distanceLabel;
#end
#import "CustomDetailCell.h"
#implementation CustomDetailCell
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
}
#end