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.
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'm attempting to put an instance of UIDatePicker in the accessory view of a UITableView cell, and have been following this SO thread as a template. However, it looks as if the picker is being placed above the cell entirely:
Below is the code I'm using to try to add a Date Picker to the accessory view of a UITableView:
- (UITableViewCell *)tableView:(UITableView *)tableView cellNewRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"RowCell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
cell.backgroundColor = [UIColor colorWithRed:0.922 green:0.937 blue:0.949 alpha:1];
switch (indexPath.row) {
case EmployeeOvertimeRow:
cell.textLabel.text = NSLocalizedString(#"Test", #"One");
_datePicker = [[UIDatePicker alloc]init];
_datePicker.datePickerMode = UIDatePickerModeTime;
//OLD: cell.accessoryView = _datePicker;
//POST EDIT
[cell.contentView addSubview:_datePicker];
break;
default:
break;
}
return cell;
}
Does anyone have any guidance on what I'm doing wrong or how to fix this?
The accessoryView of a UITableViewCell is surely not what you think : it's the little view at the right of the cell, typically, it's an arrow, and it's pretty small, not made to be the width of the screen at all. You should try adding your view to the contentView. You will need to set a bigger height for your cell in the heightForRowAtIndexPath method, too.
Using Xcode 4.6, I am trying to display a typical UITableView with its cells with subtitles.
If I am not wrong, the code is this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
Test *myTest = [self listTests][indexPath.row];
cell.textLabel.text = [myTest name];
UIFont *cellFont = [UIFont systemFontOfSize:16.0];
cell.textLabel.font = cellFont;
UIFont *detailFont = [UIFont systemFontOfSize:12.0];
NSMutableString *detailText = [NSMutableString stringWithFormat:#"%d", [myTest numQuestions]];
[detailText appendString:#" preguntas."];
cell.detailTextLabel.text = detailText;
cell.detailTextLabel.font = detailFont;
return cell;
}
For some reason, it never passes through this line of code:
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
so the cell is never initialized with UITableViewCellStyleSubtitle.
It is somehow getting ALWAYS FROM THE BEGINING a valid cell when doing [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
What can I be doing wrong?
It is really weard. I always use this code and it normally works. What else can I be doing wrong somewhere else?
This happens when your cell is defined using a storyboard prototype. In this case the reusable cells are pre-created using the initWithCoder: method, so if (cell == nil) never gets hit. See this question for more information.
Since it appears that you would like to use a cell with a standard style, changing the table to not use a storyboard prototype or setting the prototype to "Subtitle" should fix this problem.
I have a very strange issue with the tableview:
I have a table cell where I created a segue to another tableview
I initiate the table cell using the below code with style "UITableViewCellStyleSubtitle":
The problem I have is that touch of the table cell is not triggering the segue(prepareForSegue is not called), but if I change the table cell style to default, then it works.
Does anyone know, what is wrong? Thanks a lot!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * const kPlacesCellIdentifier = #"Cell99";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kPlacesCellIdentifier];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kPlacesCellIdentifier];
//cell.editingAccessoryType = UITableViewCellAccessoryDetailDisclosureButton;
CountryCustomers *aCountryCustomer = [_countryCustomersList objectAtIndex:indexPath.row];
cell.textLabel.text = aCountryCustomer.countryName;
NSString *detailTextLable = [#"Users:" stringByAppendingString:[NSString stringWithFormat:#"%d", aCountryCustomer.userNumbers]];
cell.detailTextLabel.text = detailTextLable;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
//add the national flag
NSString *imageName = [NSString stringWithFormat:#"%#.png",aCountryCustomer.countryName];
cell.imageView.image = [UIImage imageNamed:imageName];
return cell;
}
It happens because you are create another cell, you shouldnt call
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kPlacesCellIdentifier];
after
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kPlacesCellIdentifier];
since dequeueReusableCellWithIdentifier already creates the cell
To change the cell type go to the story board and change, select the cell, and change style to Subtitle