tablview with holdgesture in cells un-highlighting - objective-c

I have my table view and the cells within it have the UILongPressGestureRecognizer added to them. The issue is that once a cell it touched it gets highlighted, but once my long gesture starts (holding the button) the highlighting goes away. The gesture works and its still being held but its a little confusing to the user because they dont know if its still being held. How can I make the cell stay highlighted throughout the hold.
some code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
//add long press gesture for the audio AB (eventually VC and TP as well) list
//so that users can hold the cell and after 5 seconds have the dialpad for editing that entry
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]
initWithTarget:self
action:#selector(handleLongPress:)];
longPress.minimumPressDuration = 1;
[cell addGestureRecognizer:longPress];
}
cell.textLabel.text = [self.tableArray objectAtIndex:indexPath.row];
return cell;
}
- (void)handleLongPress:(UILongPressGestureRecognizer*)sender
{
//used to get indexPath of cell pressed
UITableViewCell *cell = (UITableViewCell *)[sender view];
//get the indexPath of cell pressed
NSIndexPath *indexPath = [self.myTableView indexPathForCell:cell];
//use the index press to figure out the proper join to hold
self.sharedJoinNumber = indexPath.row+286 ;
}

I did get this problem fixed by using
//highlight the apprioriate cell
[self.myTableView selectRowAtIndexPath:indexPath animated:FALSE scrollPosition:UITableViewScrollPositionNone];
right after - (void)handleLongPress:(UILongPressGestureRecognizer*)sender
however now if the hold is canceled the next cell clicked needs to be double taped to be highlighted. Basically the next tap after the longpress is cancelled doesnt get noticed. but i think this is a separate questing which i will file accordingly. the above code does fix my problem

Related

Set text to textfield of table Cell in objective c outside UITableView delegate methods

I am new to objective C,and have made a demo app.
In this app I am having a UITableView which contains textField.When I taps a button(sign in using Facebook), after successfully login from Facebook it come back to my TableView screen,at that time i want to set values came from Facebook response to UITableView's textFields, but I am unable to do it as TableView's delegate method is calling only once.
Can anybody please help me to set text to tableView's textField outside its delegate method?
code
NSString *cellIdentifier = [[signInTableData objectAtIndex:2] objectForKey:#"cellIdentifier"];
signUpCustomCell *cell = (signUpCustomCell *)[signUpTable dequeueReusableCellWithIdentifier:cellIdentifier];
//NSLog(#"=====my username cell====%#",indexPath);
if(cell == nil)
{
cell = (signUpCustomCell *)[[signUpCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.backgroundColor = [UIColor clearColor];
cell.tableField.delegate = self;
CGRect frmTxt = cell.tableField.frame;
frmTxt.size.width = signUpTable.frame.size.width + TRAIL_MARGIN_CELL_CONTENT;
cell.tableField.frame = frmTxt;
cell.tableField.text = #"hello test";
If you know at which row your UITextField is then you can query UITableView for a cell at given IndexPath.
NSIndexPath *ip = [NSIndexPath indexPathForRow:0 inSection:0];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:ip];
You'll need to cast that cell to what ever custom cell you are using to access the UITextField inside and your custom UITableViewCell should have a property that points to the UITextField or a method that would update the text.
-(void)viewWillAppear or -(void)viewDidApper overrides in your UIViewController subclass could be the places to do that, after you have loaded your data to the UITableView.
You need to set values into UITextField in delegate
cellForRowAtIndexPath as it is rendered for every cell of UITableView.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"yourcellidentifier"];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"yourcellidentifier"] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
cell.yourTextView.text= textforRow;
return cell;
}

UITableView Cell highlight / retain selected value IOS

I have UIView(LeftMenu) with UITableView (UITableViewStylePlain). I have around 7 controllers , Where on selection of each cell I wanna push corresponding controller. I tried custom highlight for cell with yellow color as below ,
UIColor *yel=[[UIColor alloc]initWithRed:240/255.0 green:197/255.0 blue:67/255.0 alpha:1.0];
UIView *bgColorView = [[UIView alloc] init];
[bgColorView setBackgroundColor:yel];
[cell setSelectedBackgroundView:bgColorView];
in cellForRowAtIndexPath. But I am unable to retain selected cell If I move to next controller. In didSelectRowAtIndexPath , I am capturing last selected index ( When I select new cell , old should be unhighlighted). But it seems , If I make custom its not retaining. If I keep UITableViewCellSelectionStyleNone , cell.backgroundColor it works. But not highlighting :(
[[NSUserDefaults standardUserDefaults]setInteger:indexPath.row forKey:#"SSLastSelectedLeftMenuIndex"];
I am initializing UIView(LeftMenu) with frame.
Issue : Gray Color on Highlight after few mins custom yellow highlight coming and Not retaining selected cell color.
I know I am missing some silly thing. But its eating my time. Advance thanks :)
Update:-
below is my -cellForRowAtIndexpath method
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
if([[NSUserDefaults standardUserDefaults]integerForKey:#"SSLastSelectedLeftMenuIndex"]==indexPath.ro‌w)
{
///<HIGHLIGHT CODE>;
}
to select the last selectd cell .. (try)
- (void)viewWillAppear
{
[uper viewWillAppear];
//hear u can set the selected cell
//get indexpath of row
int k = your saved row
NSIndexPAth *path = [NSIndexPath indexPathWithIndex:k];//if u hav single section or u can use other class method
[tableView selectRowAtIndexPath:_selctedIndex animated:NO scrollPosition: UITableViewScrollPositionNone];//hear u are directly setting the last selected cell once view will appear
}
hop this helps u :)
if u are using UITableViewCell then u do something like this,for yellow color for selecting the cell
//in controller do like this
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if(cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
UIColor *yel=[[UIColor alloc]initWithRed:240/255.0 green:197/255.0 blue:67/255.0 alpha:1.0];
UIView *bgColorView = [[UIView alloc] init];
[bgColorView setBackgroundColor:yel];
[cell setSelectedBackgroundView:bgColorView];
}
return cell;
}
in the subclassed table cell there is one method, to display yellow color for selecting the cell
//in CustomCell.m
//in the custom cell set the color for selected state
//override this method
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
if(selected)
{
//same code of urs
UIColor *yel=[[UIColor alloc]initWithRed:240/255.0 green:197/255.0 blue:67/255.0 alpha:1.0];
UIView *bgColorView = [[UIView alloc] initWithFrame:self.bounds];//for entaire cell,set the frame
[bgColorView setBackgroundColor:yel];
[self setSelectedBackgroundView:bgColorView];
}
}
You have misunderstood selection and highlighting a cell you should change your cellForRowAtIndexPath like below to select the previously selected item.
before that Declare a globle variable _selctedIndex of type NSIndexpath to store the last selected cell
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
UIColor *yel=[[UIColor alloc]initWithRed:240/255.0 green:197/255.0 blue:67/255.0 alpha:1.0];
UIView *bgColorView = [[UIView alloc] init];
[bgColorView setBackgroundColor:yel];
[cell setSelectedBackgroundView:bgColorView];
}
if([[NSUserDefaults standardUserDefaults]integerForKey:#"SSLastSelectedLeftMenuIndex"]==indexPath.row)
{
//<HIGHLIGHT CODE>;
_selctedIndex=indexPath; //code Updated
}
return cell;
}
After your tableView has reloaded call the below line of code
[tableView selectRowAtIndexPath:_selctedIndex animated:NO scrollPosition:UITableViewScrollPositionTop];
}
The UITableViewCell class will assign the view you have mentioned to the property selectedBackgroundView instead of the Default blue color view for showing in the background when a cell is selected
I ran into the exact same problem in a project, when tapping on a cell long enough to engage highlight then moving to a scroll the UITableView holds onto the highlighted index somehow so that the next attempt to select uses that previous indexPath.
To resolve I did the following
Add Property to Track Offending indexPath
...
#property (nonatomic,strong) NSIndexPath *cachedPath;
...
Track indexPath with didUnhighlightRowAtIndexPath
- (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
self.cachedPath = indexPath;
}
On Drag reload offending indexPath
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
if (self.cachedPath)
{
[self.tableView reloadRowsAtIndexPaths:#[self.cachedPath] withRowAnimation:UITableViewRowAnimationNone];
}
self.cachedPath = nil;
}
For good measure clear the property on selection
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.cachedPath = nil;
}

UITableView not selecting properly

I am working on an iPhone app, where I have a UITableView which is being populated with an XML feed through a URL.
Say for instance three of the cells are populated.
If I tap on the first cell nothing happens, however if I tap on the second or third cell, it takes me to the second screen related to cell one, and the same happens with the other cells - tap on it nothing, tap on another and it takes me to the second screen of the previous one selected.
I have never had this happen before and am rather confused.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"UITableViewCell"];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:#"UITableViewCell"];
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
LocationsItem *atm = [[locations atms] objectAtIndex:[indexPath row]];
[[cell textLabel] setText:[atm atmName]];
float distance = [[atm atmDistance] floatValue];
NSString *distanceString = [NSString stringWithFormat:#"%0.2f miles from current location", distance];
[[cell detailTextLabel] setText:distanceString];
return cell;
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
LocationsItem *atm = [[locations atms] objectAtIndex:[indexPath row]];
ATMDetailsController *detailsController = [[ATMDetailsController alloc] init];
[detailsController setCurrentATM: atm];
[[self navigationController] pushViewController:detailsController animated:YES];
}
Thanks,
Nick
You answered your own question. The issue is that you used tableView:deselectRowAtIndexPath: instead of tableView:didSelectRowAtIndexPath:
What is noteworthy is that this is from the unfortunate fact that deselect comes before did in the dictionary, and therefore, xcode's normally awesome code completion hinks you!
Now to go get those hours of debugging back!

Cell accessorytype doesn't reload on [tableview reloadData]

I'm very new to iPhone programming, so my problem might be caused by total lack of knowledge of very basic principles.
I'm developing an iPhone app that has two Views. The first view has two buttons, when one of the buttons is pressed, a modalview popsup with a tableview. This table view is populated differently depending of what button is pressed. If button button1 is pressed the tableview is populated with the button1Data. The user can select cells, and if this is done the cells accessorytype is set to UITableViewCellAccessoryCheckmark. I then save the name of the checked cells into tableViewListChecked, so it can later be decided what cell are supposed to be checked as the data changes.
The problem is as following: after the modalview is dismissed, and I select button2 the cells that was selected in button1Data is still selected in button2Data. It is clear to me that the function [theTableView reloadData] is working since the data does change, however the accesorytupes is still the same until i scroll the cells off the screens.
P.S. If I do in fact scroll cells of the screen there accessorytype is set correctly.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryNone;
}
else if ([tableViewListChecked containsObject:[NSString stringWithString:cell.textLabel.text]]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
cell.textLabel.text = [tableViewList objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (![tableViewListChecked containsObject:[NSString stringWithString:cell.textLabel.text]]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[tableViewListChecked addObject:[NSString stringWithString:cell.textLabel.text]];
}
else if ([tableViewListChecked containsObject:[NSString stringWithString:cell.textLabel.text]]) {
cell.accessoryType = UITableViewCellAccessoryNone;
[tableViewListChecked removeObject:[NSString stringWithString:cell.textLabel.text]];
}
}
Thanks for you help!
If the cell is not nil (if it has been dequeued from the table view) then you don't actually, as it is, change the accessory type. Drop the else, ie change
else if ([tableViewListChecked containsObject:[NSString stringWithString:cell.textLabel.text]]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
to
if ([tableViewListChecked containsObject:[NSString stringWithString:cell.textLabel.text]]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
It sounds like you are reusing the same instance of the UITableView each time you present the modal view, in which case, what is happening to the tableViewListChecked array? You are swapping out data in the tableViewList; but are you employing some strategy to persist the list of checked items between taps on button1 and button2?
If the guys here didn't helped you, you can just set:
cell.accessoryType = UITableViewCellAccessoryNone every time the user clicks on button2

UITableViewCell selection stays in all cells !

I am still in the process of getting myself acquainted with the iPhone SDK.
This is what I am trying to do :
I have a UIScrollView and each scroll view has an UITableView and I have implemented a custom UITableViewCell.
The desired functionality is initially there is no selection, then the user selects the row and scrolls and makes another selection in the next scroll view and continues. I want the selection to stay, so the user can change the selection at a later point.
However what is happening in my case is - the first and the second UITableViews are fine, the selected row stays selected, but in the third UITableView I see a row "already" selected which is same as the first UITableView. I do not want to see any selected.
I know I am doing something stupid but cannot figure out what. Any help would be really appreciated.
Thanks,
Amy
Here are the relevant data source and delegate methods.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%s", __FUNCTION__);
static NSString * ChoiceTableCellIdentifier = #"ChoiceTableCellIdentifier";
choiceTableCell = (ChoiceTableCell *)[tableView dequeueReusableCellWithIdentifier:ChoiceTableCellIdentifier];
if( choiceTableCell == nil )
{
choiceTableCell = [[[ChoiceTableCell alloc]
initWithFrame:CGRectZero
reuseIdentifier:ChoiceTableCellIdentifier] autorelease];
}
return choiceTableCell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%s", __FUNCTION__);
int newRow = [indexPath row];
int oldRow = [lastIndexPath row];
if ( (newRow != oldRow) || (newRow == 0) )
{
UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
UIImageView *indicatorN = (UIImageView *)[newCell.contentView viewWithTag:SELECTION_INDICATOR_TAG_1];
indicatorN.image = [UIImage imageNamed:#"selected.png"];
newCell.backgroundView.backgroundColor = [UIColor clearColor];
UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:lastIndexPath];
UIImageView *indicatorO = (UIImageView *)[oldCell.contentView viewWithTag:SELECTION_INDICATOR_TAG_1];
indicatorO.image = [UIImage imageNamed:#"notSelected.png"];
oldCell.backgroundView.backgroundColor = [UIColor clearColor];
lastIndexPath = indexPath;
}
}
You are reusing a cell that has the image "selected.png".
In the method cellForRowAtIndexPath you have to "select" or "deselect" your cell depending your last selection. That is: if indexPath is equals to lastIndexPath you have to put the background "selected.png", else "noSelected.png".
When you reuse a cell, it keep its previous state, so you have to initialize it all.