UITableView cell's seperators disappear when selected - ios

When I select a UITableViewCell and start scrolling to the point where the cells disappear from the screen, the seperators on those cells disappear once they reappear on the screen.
Delegate:
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if(cell == nil){
if(Type == Scene){
Group *scene = [[appdata getScenes]objectAtIndex:lastRequestedPropertyPosition];
[selectedArray addObject:scene.id];
}else if(Type == Product){
Device *device = [[appdata getDevices]objectAtIndex:lastRequestedPropertyPosition];
[selectedArray addObject:device.id];
}
}else{
[selectedArray addObject:[NSNumber numberWithInt:cell.tag]];
}
}
Datasource:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"protoCell" forIndexPath:indexPath];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"protoCell"];
}
Group *group = [[appdata getScenes] objectAtIndex:indexPath.row];
if(group != nil){
[cell.textLabel setText:group.name];
}
cell.tag = group.id.intValue;
return cell;
}
Can anyone tell what went wrong here?
Thanks
EDIT
Using this just makes the separator disappear on select instead of just keeping the separator there.
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if(cell == nil){
if(Type == Scene){
Group *scene = [[appdata getScenes]objectAtIndex:lastRequestedPropertyPosition];
[selectedArray addObject:scene.id];
}else if(Type == Product){
Device *device = [[appdata getDevices]objectAtIndex:lastRequestedPropertyPosition];
[selectedArray addObject:device.id];
}
}else{
[selectedArray addObject:[NSNumber numberWithInt:cell.tag]];
}
}

The cause of my issue was the fact I used a blue color shade to show a cell being selected. This shade however was a little too big. It was covering the seperator

In tableView:didSelectRowAtIndexPath, if you send both messages below, the issue is visually resolved (with the probable performance cost).
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
For this to work (for me), deselectRowAtIndexPath:animated: must contain animated:YES. The animation used for reloadRowsAtIndexPaths:withRowAnimation: doesn't matter.

Related

Obj-C - Deselect the selected cell when another cell is tapped?

I'm currently using the below code for didSelectRowAtIndexPath. With the way I have my code written now, if a user taps a cell a green checkmark appears. If they tap the same cell again, the green checkmark disappears. That said, I want to make it so that if the user taps a different cell after making a selection, the green checkmark should disappear from the previously selected cell. How can I accomplish this?
ViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if(_selectedRowIndex && indexPath.row == _selectedRowIndex.row) {
ClientTableViewCell *cell2 = [tableView cellForRowAtIndexPath:indexPath];
cell2.greenCheck.image = [UIImage imageNamed:#""];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
_selectedRowIndex = nil;
}
else { self.selectedRowIndex = indexPath;
ClientTableViewCell *cell2 = [tableView cellForRowAtIndexPath:indexPath];
NSDictionary *client = self.sectionClients[indexPath.section][indexPath.row];
cell2.greenCheck.image = [UIImage imageNamed:#"added.png"];
NSLog(#"SELECTED");
}
[tableView beginUpdates];
[tableView endUpdates];
}
You can store the last selected indexpath, when a new cell is selected, you get the previous cell with the stored indexpath and deselect it.
#implementation ViewController
NSIndexPath *lastIndexPath;
...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if (lastIndexPath != nil){
UITableViewCell *oldCell = [self.tableView cellForRowAtIndexPath:lastIndexPath];
oldCell.accessoryType = UITableViewCellAccessoryNone;
}
if(lastIndexPath != indexPath) {
lastIndexPath = indexPath;
UITableViewCell *cell2 = [tableView cellForRowAtIndexPath:indexPath];
cell2.accessoryType = UITableViewCellAccessoryCheckmark;
}else{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
lastIndexPath = nil;
}
[tableView beginUpdates];
[tableView endUpdates];
}

How To Get TableviewCell Selected Check Mark Row Values Using Objective C?

I need to create tableviewcell checkmark selected row title label and detail label values get after clicking the submit button.
- (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] autorelease];
}
if ([indexPath compare:self.lastIndexPath] == NSOrderedSame)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
// UITableView Delegate Method
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
cell = [tableView cellForRowAtIndexPath:indexPath];
NSLog(#"Section:%ld Row:%ld selected and its data is %# %#",(long)indexPath.section,(long)indexPath.row,cell.sector_Label.text,cell.textLabel.text);
selectedIndex = indexPath.row;
[tableView reloadData];
}
- (IBAction)Submit_Click:(id)sender {
// Here I need to get tableview cell check mark selected cell label values.
}
Check this:
-(IBAction)Submit_Click:(id)sender {
// Here I need to get tableview cell check mark selected cell label values.
if (selectedIndex >= 0) {
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:selectedIndex inSection:0];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSLog(#"detailTextLabel: %#", cell.detailTextLabel.text);
NSLog(#"title: %#", cell.textLabel.text);
}
}
You can use indexPathsForSelectedRows
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
cell = [tableView cellForRowAtIndexPath:indexPath];
if(cell.isSelected)
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
else
{
[cell setSelected:YES animated:YES]
}
}
-(IBAction)Submit_Click:(id)sender {
// Here I need to get tableview cell check mark selected cell label values.
NSArray *indexes = [self.tableview indexPathsForSelectedRows];
if (indexes.count > 0)
{
//do your stuff as you get selected row index array
}
}

store selected cells textLabel text in an array

How do i store all selected cells text label text in a NSMutableArray?
How do i remove the correct cells text from the NSMutableArray when a cell is deselected?
What i have this far:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
static NSString *CellIdentifier = #"Cell";
PFTableViewCell *cell = (PFTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[PFTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if ([self.allSelectedUsers containsObject:indexPath]) {
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
NSLog(#"Yeeees");
}else{
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
// Configure the cell
cell.textLabel.text = object[#"username"];
return cell;
}
This is when i'm selecting a cell:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if ([self.allSelectedUsers containsObject:indexPath]) {
[self.allSelectedUsers removeObject:indexPath];
}
else{
[self.allSelectedUsers addObject:indexPath];
}
NSLog(#"%d", self.allSelectedUsers);
[tableView reloadData];
}
When i check the log it doesn't display anything about the cells text label.
As I can't see how you're getting object instance, I suggest you to get back cell and read the title again.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// Lazy initialise array
if (!self.allSelectedUsers) {
self.allSelectedUsers = [NSMutableArray new];
}
// Take action
if ([self.allSelectedUsers containsObject:indexPath]) {
[self.allSelectedUsers removeObject:indexPath];
} else {
[self.allSelectedUsers addObject:indexPath];
}
[tableView reloadData];
// Logging all selected users
for (NSIndexPath *sIndexPath in self.allSelectedUsers) {
NSLog(#"%#", [tableView cellForRowAtIndexPath:sIndexPath].textLabel.text);
}
}
You are currently storing NSIndexPath objects, not NSString objects, so it's not exactly what your question is asking. With your PFTableViewController, you have access to the selector objectAtIndexPath:.
for (NSIndexPath *indexPath in self.allSelectedUsers) {
NSLog(#"%#", [self objectAtIndexPath:indexPath][#"username"]);
}
Note: You shouldn't be calling reloadData in your didSelectRowAtIndexPath: responder; change the accessory type for the cell instead.
[[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark];
You should also implement didDeselectRowAtIndexPath: to know when a user deselects a row.

UITableViewCell content of previous row is still visible on Cell reload

I have a UITableView that has 2 different custom UITableViewCell with 2 different unique identifiers.
I load the first custom UITableViewCell on Load and then the second custom UITableViewCell on Cell Select.
I know that my problem is related to the way I am reusing my Cells. But I've tried using
routineSearchSelectedResultCell * cell = (routineSearchSelectedResultCell*)[tableView dequeueReusableCellWithIdentifier:nil]; and the result is that the new UITableViewCell is empty and the properties do not get populated.
I've also tried [[[cell contentView] subviews] makeObjectsPerformSelector: #selector(removeFromSuperview)]; but give me the same results.
How could I go around this problem??
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (idp && idp.row == indexPath.row ) {
return [self tableViewRoutineSelectedResult:tableView cellForRowAtIndexPath:indexPath];
}
NSString *cellIdentifier = #"routineSearchCell";
routineSearchCell * cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[routineSearchCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
cell.routineName.text = _myDownloadedInfo[#"routines"][indexPath.row][#"routine"][#"routineName"];
cell.routineAuthor.text = _myDownloadedInfo[#"routines"][indexPath.row][#"routine"][#"username"];
return cell;
}
- (routineSearchSelectedResultCell *)tableViewRoutineSelectedResult:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary* myRoutine = _myDownloadedInfo[#"routines"][indexPath.row][#"routine"];
[self sortOutRoutineImages:myRoutine[#"routineType"]];
NSString *cellIdentifier = #"routineSearchSelectedResultCell";
routineSearchSelectedResultCell * cell = (routineSearchSelectedResultCell*)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[routineSearchSelectedResultCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
cell.label1.text =#"test";
cell.contentView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"BlackGradientSearch"]];
cell = [self iconRoutineImagesController:cell];
cell.imgInstruction.image = [UIImage imageNamed:#"InstructionSearchWhite"];
cell.imgVideos.image = [UIImage imageNamed:#"VideoSearchWhite"];
cell.routineName.text = myRoutine[#"routineName"];
[cell.download setBackgroundImage:[UIImage imageNamed:#"DownloadSearchWhite"] forState:UIControlStateNormal];
return cell;
}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ( idp ) {
NSIndexPath* pIdp = [[NSIndexPath alloc] init];
pIdp = idp;
idp = indexPath;
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
[tableView reloadRowsAtIndexPaths:#[pIdp] withRowAnimation:UITableViewRowAnimationRight];
[tableView endUpdates];
} else {
idp = [[NSIndexPath alloc]init];
idp = indexPath;
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
[tableView endUpdates];
}
}
try to override
-(void)prepareForReuse
If a UITableViewCell object is reusable—that is, it has a reuse identifier—this method is invoked just before the object is returned from the UITableView method dequeueReusableCellWithIdentifier:. For performance reasons, you should only reset attributes of the cell that are not related to content, for example, alpha, editing, and selection state. The table view's delegate in tableView:cellForRowAtIndexPath: should always reset all content when reusing a cell. If the cell object does not have an associated reuse identifier, this method is not called. If you override this method, you must be sure to invoke the superclass implementation.
see the document
I think you are using the labels and they are overlapping..
Try to use this, It might help you..
for(UIView *view in cell.subviews){
if([view isKindOfClass:[UILabel class]]){
[view removeFromSuperview];
}
}

ios - Expand table view cell like Twitter app

I want to have the same behavior as Twitter app when selecting a tweet that is : expanding the row and adding supplementary content.
So this is not only a basic row resize. I think i need 2 different custom cells, so i did something like that :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([indexPath compare:self.selectedIndexPath] != NSOrderedSame) {
FirstCell *cell = [tableView dequeueReusableCellWithIdentifier:#"FirstCell"];
if (!cell) {
cell = [[FirstCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"FirstCell"];
}
cell.firstnameLabel.text = [[self.items objectAtIndex:indexPath.row] objectForKey:#"firstname"];
return cell;
}
else {
SecondCell *cell = [tableView dequeueReusableCellWithIdentifier:#"SecondCell"];
if (!cell) {
cell = [[SecondCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"SecondCell"];
}
cell.firstnameLabel.text = [[self.items objectAtIndex:indexPath.row] objectForKey:#"firstname"];
cell.lastnameLabel.text = [[self.items objectAtIndex:indexPath.row] objectForKey:#"lastname"];
return cell;
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([indexPath compare:self.selectedIndexPath] == NSOrderedSame) {
return 80.0;
} else {
return 44.0;
}
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.selectedIndexPath = indexPath;
[tableView reloadData];
}
My problem here is that i want to keep a fluid animation like Twitter app which is not my case because of [tableView reloadData] (which is mandatory i think since i have 2 different custom cell).
So anyone knows a workaround to my needed or maybe someone knows how Twitter app is handling this animation stuff ?
You want to reload that cell with an animation:
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
[tableView beginUpdates];
[tableView endUpdates];
this triggers an update of the cell row sizes for the whole tableView.... referenced from :iPhone - Smooth animation for UITableViewCell height change including content update
Happy Coding!
It is actually rather easy to implement this using two custom cells like you originally intended by just combining your original code with rooster117's solution. Replace [tableView reloadData] in your tableView:didSelectRowAtIndexPath: with:
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView endUpdates];
and you should have your solution.

Resources