With iOS 8 I have come up with some issues using UITableView. In fact, I have a NavigationController and its RootController set as my ViewController with UITableView. Then I configure my table, add cells and set their style to UITableViewCellStyleValue1 and nothing happens at the time it should display a detailed text label to the right of the textLabel. I suppose that there is some missing constraints preventing from displaying the whole cell's view.
My code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"STI";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier];
}
cell.textLabel.text = self.dwarves[indexPath.row];
cell.detailedLabel.text = #"Detailed text";
UIImage *img = [UIImage imageNamed:#"star"];
cell.imageView.image = img;
return cell;
}
What I get:
I think the property you're looking for is cell.detailTextLabel, not cell.detailedLabel.
Take a look at this post.
The code I use for setting up my detailed text:
if (indexPath.row < 7) {
cell.detailTextLabel.text = #"First";
} else {
cell.detailTextLabel.text = #"Second";
}
I'm in the process of updating an old app for iOS 8 and ran into the same issue. I haven't discovered the root of the problem yet, but calling layoutSubviews for the cell before returning it fixed it for me.
...
[cell layoutSubviews];
return cell;
}
Related
I'm working on an iOS project .I created an UITableView to display a list of drones . Everything works fine but I noticed that there is a bug when I click on the cell to display the details of the drone . As u can see in the images below.
When the tableView get loded
When clicked on cell
and this my code when I select a cell :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *_storyboardName = #"Main";
UIStoryboard *_storyboard = [UIStoryboard storyboardWithName:_storyboardName bundle: nil];
DroneDetailsViewController *detailsVC = [_storyboard instantiateViewControllerWithIdentifier:#"DroneDetailsViewController"];
detailsVC.droneObj = [drones objectAtIndex:indexPath.row];
[self.navigationController pushViewController:detailsVC animated:YES];
[detailsVC.navigationController setNavigationBarHidden:NO animated:YES];
}
This my code for cellForRowAtIndexPath :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"drone";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
DroneObject *droneObjDisplay = nil;
droneObjDisplay = [drones objectAtIndex:indexPath.row];
NSData *data = [[NSData alloc]initWithBase64EncodedString:droneObjDisplay.modelMSide options:NSDataBase64DecodingIgnoreUnknownCharacters];
[self initCellWithComponents:cell :data :droneObjDisplay.modelName :droneObjDisplay.modelNumber];
return cell;
}
and this the initCelWithComponents :
- (void)initCellWithComponents :(UITableViewCell *)cell :(NSData *)dataImage :(NSString *)title :(NSString *)subTitle {
UIView *viewCell = [[UIView alloc] initWithFrame:CGRectMake(VIEW_MARGIN, VIEW_MARGIN, widthtScreen-20, VIEW_IMAGE_HEIGHT)];
viewCell.layer.borderColor = [UIColor colorWithHexString:NSLocalizedString(#"border_color", nil)].CGColor;
viewCell.backgroundColor = [UIColor whiteColor];
viewCell.layer.borderWidth = 0.5f;
UIImageView *image = [[UIImageView alloc]initWithFrame:CGRectMake(VIEW_MARGIN,VIEW_MARGIN, VIEW_IMAGE_HEIGHT-(2*VIEW_MARGIN),VIEW_IMAGE_HEIGHT-(2*VIEW_MARGIN))];
image.image=[UIImage imageWithData:dataImage];
[viewCell addSubview:image];
UILabel *titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(image.frame.size.width+2*VIEW_MARGIN, VIEW_MARGIN, viewCell.frame.size.width-(VIEW_IMAGE_HEIGHT-(4*VIEW_MARGIN)), 21)];
titleLabel.text = title;
titleLabel.textColor = [UIColor blackColor];
[titleLabel setFont:[UIFont systemFontOfSize:15]];
[viewCell addSubview:titleLabel];
UILabel *subTitleLabel = [[UILabel alloc]initWithFrame:CGRectMake(image.frame.size.width+2*VIEW_MARGIN, 3*VIEW_MARGIN, viewCell.frame.size.width-(VIEW_IMAGE_HEIGHT-(4*VIEW_MARGIN)), 21)];
subTitleLabel.text = subTitle;
subTitleLabel.textColor = [UIColor blackColor];
[subTitleLabel setFont:[UIFont systemFontOfSize:13]];
[viewCell addSubview:subTitleLabel];
cell.contentView.backgroundColor = [UIColor colorWithHexString:NSLocalizedString(#"gray_background", nil)];
[cell.contentView addSubview:viewCell];
}
any ideas how to fix that ?!
Your cell's style is UITableViewCellStyleSubtitle and you also adding title and subtitle label manually also.
If you are using cell's style as UITableViewCellStyleSubtitle then you can directly use
cell.textLabel.text = #"your title label's text";
cell.detailTextLabel.text = #"your detail label's text";
If you will add another label then it will creates duplicate!!!!
Since you are initialising UIView and UILabel in method inside cellForRowAtIndexPath and adding them as subview, these controls are being added to your cell each time cell is reloaded. Below code identifies each cell with a unique identifier and loads the cell only if that particular cell is not available in UITableView.
I have written droneObjDisplay.droneId to uniquely identify cell, you can write anything for droneObjDisplay.__ that is unique identifier of your object.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
DroneObject *droneObjDisplay = nil;
droneObjDisplay = [drones objectAtIndex:indexPath.row];
NSString *CellIdentifier = [NSString stringWithFormat:#"drone_%d", droneObjDisplay.droneId];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
NSData *data = [[NSData alloc]initWithBase64EncodedString:droneObjDisplay.modelMSide options:NSDataBase64DecodingIgnoreUnknownCharacters];
[self initCellWithComponents:cell :data :droneObjDisplay.modelName :droneObjDisplay.modelNumber];
}
return cell;
}
Hope it helps.
The TableViewCell could be designed and used by either one of the following ways,
If you are using the storyboard then you can simply design the prototype cell on the TableView on storyboard itself and then giving an identifier to the cell. If you are using this way then add the component on the storyboard only and give tag to each component to access it in the code if you are not subclassing the UITableViewCell, and dequeue the cell as below,
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
UILabel *labelValue = (UILabel*) [cell viewWithTag:10];
Design the TableViewCell on the storyboard as you did in 1 way and then simply create a subclass of UITableViewCell class and set that class as a Custom Class of the cell by selecting the cell on storyboard, this way you can create the outlet of each component in the cell and you do not need to access the component by the tags. Below is the code to dequeue the cell,
CellSubClassed *cell = (CellSubClassed*)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
cell.labelXYZ.text = arrayDataSource[indexPath.row][#"key"];
This is the old way before storyboard was introduced, Create subclass of UITableView cell and create a xib file with the same name you give to UiTableViewCell subclass, create the outlets of component you want to access. Below is the code to dequeue cell,
NSArray *nib;
static NSString *strNibName = #"CustomCell";
nib = [[NSBundle mainBundle] loadNibNamed:strNibName owner:self options:nil];
CustomCell *cell = [nib objectAtIndex:0];
cell.imageView.image = arrayDataSource[indexPath.row];
The last way is using TableView's default cells, just create the tableView on storyboard/xib and dequeue the cell as below,
static NSString *cellIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = #"xyz";
The default tableView cell styles are,
UITableViewCellStyleDefault
UITableViewCellStyleSubtitle
UITableViewCellStyleValue1
UITableViewCellStyleValue2
You can read about more on Apple Developer docs here.
So in your case you are mixing the two ways of dequeuing the cell, if you want to add the component manually as you did and you don't want to design the component on the storyboard or Xib then you just create the subclass of UITableView cell and then create the component in the awakeFromNib method and dequeue the cell as explained in 3 way.
Hope it helps you.
Ok finally, after getting your answers guys , I created a Custom Cell a subclass of UITableViewCell and I added all my components there . The main problem was how I will call it without UI (storyboard or xib ) just by code .
So after the creation of the custom cell I added this line to my viewdidload :
[self.tableView registerClass:[CustomCellTableViewCell class] forCellReuseIdentifier:#"CustomCellTableViewCell"];
then in the cellForRowAtIndexPath I just added the custom cell :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
DroneObject *droneObjDisplay = nil;
droneObjDisplay = [drones objectAtIndex:indexPath.row];
static NSString *identifier = #"CustomCellTableViewCell";
CustomCellTableViewCell *cell = (CustomCellTableViewCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
NSData *data = [[NSData alloc]initWithBase64EncodedString:droneObjDisplay.modelMSide options:NSDataBase64DecodingIgnoreUnknownCharacters];
cell.image.image = [UIImage imageWithData:data];
cell.titleLabel.text = droneObjDisplay.modelName;
cell.subTitleLabel.text = droneObjDisplay.modelNumber;
return cell;
}
I am trying to load my UITextView on UItableViewCell with data but unable to set text. UITextViewDelegate is also set and attached to view controller. The text string is not empty as I checked it using debugger.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CommentCellIdentifier];
//CommentCell is my custom cell with textView.
CommentCell *commentsCell = (CommentCell*)[tableView dequeueReusableCellWithIdentifier:CommentCellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CommentCellIdentifier];
}
//Setting the images for all buttons in service row.
[commentsCell.deletecomment setImage:deleteComment forState:UIControlStateNormal];
[commentsCell.editcomment setImage:editComment forState:UIControlStateNormal];
commentsCell.deletecomment.layer.borderColor = [UIColor blackColor].CGColor;
commentsCell.editcomment.layer.borderColor = [UIColor blackColor].CGColor;
NSInteger commentIndex = 2;
//CommentsArray is NSArray with data.
[commentCell.comments setText:[NSString stringWithFormat:#"%#",[[commentsArray objectAtIndex:indexPath.row] objectAtIndex:commentIndex]]];
return cell;
}
Try changing this line:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CommentCellIdentifier];
to this line:
CommentCell *cell = (CommentCell*)[tableView dequeueReusableCellWithIdentifier:CommentCellIdentifier];
I was using wrong cellname. Just replaced "commentCell" with "commentsCell" and everything starts working.
[commentsCell.comments setText:[NSString stringWithFormat:#"%#",[[commentsArray objectAtIndex:indexPath.row] objectAtIndex:commentIndex]]];`enter code here`
If you do not need scrolling the textview DISABLE SCROLLING in order for the text to appear.
I am not sure if this is caused by the fact that both the tableview and textview are descendants of UIScrollView, but it could be.
It helped me when I was experiencing the same issue
I was trying to find solution almost everywhere, but I didn't find it. So, here is my problem.
I have UITableView with custom UITableViewCells.
The first cell has UIScrollView inside its Content View.
The Second cell has UILables and other basic views inside its Content View.
So, if there is UIScrollView inside the first cell, content of the second cell disappears. It appears only if the first cell scrolls out of the tableView frame.
Can anybody help me figure it out? Thank you.
Code preview
#pragma mark - UITableView Data Source
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([indexPath isEqual:_photosIndexPath]) {
static NSString *PhotosCellIdentifier = #"AdDetailsPhotosCell";
BazarAdDetailPhotosCell *cell = [tableView dequeueReusableCellWithIdentifier:PhotosCellIdentifier];
if (!cell) {
cell = [[BazarAdDetailPhotosCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:PhotosCellIdentifier];
}
cell.photoScrollView.scrollsToTop = NO;
cell.photoScrollView.delegate = cell;
[cell setPhotos:_adDetail.photos];
return cell;
}
else if ([indexPath isEqual:_adDetailsPath]) {
static NSString *DetailsCellIdentifier = #"AdDetailsDetailCell";
BazarAdDetailsDetailCell *cell = [tableView dequeueReusableCellWithIdentifier:DetailsCellIdentifier];
if (!cell) {
cell = [[BazarAdDetailsDetailCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:DetailsCellIdentifier];
}
cell.adTitleLabel.text = _adDetail.title;
cell.priceLabel.text = _adDetail.price;
// this cell content disappears
}
}
Might be issue with cell drawing on iOS 7.1, according answer on iOS 7.1 beta5 tableviewcell height showing objects outside it's range, try to clip subviews:
cell.clipsToBounds = YES;
Try it
#pragma mark - UITableView Data Source
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([indexPath isEqual:_photosIndexPath])
{
static NSString *PhotosCellIdentifier = #"AdDetailsPhotosCell";
BazarAdDetailPhotosCell *cell = [tableView dequeueReusableCellWithIdentifier:PhotosCellIdentifier];
if (!cell) {
cell = [[BazarAdDetailPhotosCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:PhotosCellIdentifier];
}
cell.photoScrollView.scrollsToTop = NO;
cell.photoScrollView.delegate = cell;
[cell setPhotos:_adDetail.photos];
return cell;
}
else {
static NSString *DetailsCellIdentifier = #"AdDetailsDetailCell";
BazarAdDetailsDetailCell *cell = [tableView dequeueReusableCellWithIdentifier:DetailsCellIdentifier];
if (!cell) {
cell = [[BazarAdDetailsDetailCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:DetailsCellIdentifier];
}
cell.adTitleLabel.text = _adDetail.title;
cell.priceLabel.text = _adDetail.price;
// this cell content disappears
return cell;
}
}
I have 2 table views I want to customise the cell style of the second view depending on the selected row in the first table view. it works when in customising the accessories but it does't for the style. am using iOS 7.1 and Xcode 5.1
as i using the following code
thanks in advance
- (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];
}
cell.detailTextLabel.textColor = [UIColor lightGrayColor];
cell.textLabel.text = [array objectAtIndex:indexPath.row];
if ([selectedRow isEqualToString:#"Cars"]) {
[cell setAccessoryType: UITableViewCellAccessoryDetailButton];
}
if ([selectedRow isEqualToString:#"Houses"]) {
NSArray *temp = [[dic objectForKey:selectedRow]valueForKey:#"Job"];
cell.selectionStyle = UITableViewCellStyleSubtitle;
cell.detailTextLabel.adjustsFontSizeToFitWidth = YES;
cell.detailTextLabel.text = [temp objectAtIndex:indexPath.row];
}
if ([selectedRow isEqualToString:#"Libraries"]) {
cell.selectionStyle = UITableViewCellStyleValue1;
}
return cell;
}
You can't change a cell's style without creating a new cell.
The line:
cell.selectionStyle = UITableViewCellStyleValue1;
makes no sense. You are trying to change the cell's selection style by passing in a enum value for a cell's style. That's two different concepts.
When you want to update a cell's style (not the selection style), you need to call UITableView initWithStyle:reuseIdentifier: again passing in the desired style.
I am having trouble removing the white border that appears between each cell inside my UITableView. I have tried using:
[myTableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
inside my viewDidLoad method, but unfortunately that does not seem to work. I am using a background image for my cells to display, and it is the border between these images that I wish to remove. The image itself is the size of each cell, and the size of each cell I set in my CustomTableViewCell class as follows:
self.contentView.frame = CGRectMake(0, 0, 320, 80);
My cellForRowAtIndexPath method is as follows:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"mycell";
MyTableViewCell *cell = (MyTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[MyTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
cell.ID.text = [[DataModel sharedInstance].ID objectAtIndex:indexPath.row];
cell.Name.text = [[DataModel sharedInstance].Name objectAtIndex:indexPath.row];
cell.Date.text = [[DataModel sharedInstance].Date objectAtIndex:indexPath.row];
[cell setBackgroundView:[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Cell.png"]]];
return cell;
}
Despite everything I have done, I am seeing a clear white border between my cells in the table. I really would like to remove this. Can anyone see what I am doing wrong?
Inside Interface Builder - change the separator to None and then the separator color to clear color:
Setting UITableView separatorColor at viewDidLoad might be too early. Try viewWillAppear instead.