Как удалить UIGestureRecognizer из ячейки таблицы
Я хочу разрешить удаление только на первой ячейке UITableView
, Этот бит прост, однако я хочу отобразить UIAlert
когда пользователь пытается провести любую другую ячейку. Опять у меня это работает с помощью UIGestureRecognizer
на каждой ячейке, кроме клетки 0.
У меня проблема, как только верхняя строка была удалена, я хочу разрешить удаление новой верхней строки. Это как если бы мне нужно удалить UIGestureRecognizer's
Я назначен на камеру, но я не могу понять, как это сделать.
Вот часть моего кода
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
BetCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BetCell"];
Bet *bet = [self.bets objectAtIndex:([self.bets count]-indexPath.row-1)];
cell.BFNeedLabel.text = bet.BFNeeded;
if (indexPath.row != 0) {
UISwipeGestureRecognizer *swipeRecognizer = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeDetected:)];
swipeRecognizer.direction = (UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight);
[cell addGestureRecognizer:swipeRecognizer];
}
return cell;
}
-(void)swipeDetected:(UIGestureRecognizer *)sender
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Info" message:@"You can only delete starting from the top cell" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
}
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
return YES;
} else {
return NO;
}
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
// If the very first row
if ((editingStyle == UITableViewCellEditingStyleDelete) && (indexPath.row == 0)) {
Bet *betObj = [self.bets objectAtIndex:([self.bets count]-indexPath.row-1)];
//Delete from array
[self.bets removeObjectAtIndex:([self.bets count]-indexPath.row-1)];
//Delete the row
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
//Attempt to remove gesture recognizer from cell 0
UISwipeGestureRecognizer *swipeRecognizer = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeDetected:)];
swipeRecognizer.direction = (UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight);
[[tableView cellForRowAtIndexPath:0]removeGestureRecognizer:swipeRecognizer];
}
}
2 ответа
Не нужно удалять жест-распознаватель. В вашем swipeDetected
выяснить, в какой ячейке вы находитесь, и показывать предупреждение, только если indexPath.row != 0
,
Ваш распознаватель жестов даст вам местоположение, которое можно перевести в координатное пространство табличного представления, поворот которого можно использовать для получения indexPath для этой ячейки.
В swipeDetected
CGPoint location = [sender locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
if ( indexPath.row != 0 {
// do alert
}
Обновление с примером кода:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"Test"];
if ( !cell ) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"test"] autorelease];
UISwipeGestureRecognizer *gr = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleCellSwipe:)];
gr.direction = UISwipeGestureRecognizerDirectionRight + UISwipeGestureRecognizerDirectionLeft;
gr.delegate = self;
[cell addGestureRecognizer:gr];
[gr release];
}
cell.textLabel.text = [NSString stringWithFormat:@"Cell %d",indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ( indexPath.row == 0 )
return UITableViewCellEditingStyleDelete;
else
return UITableViewCellEditingStyleNone;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return indexPath.row == 0;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
// do stuff
}
- (void)handleCellSwipe:(UIGestureRecognizer *)gestureRecognizer
{
if ( gestureRecognizer.state == UIGestureRecognizerStateRecognized ) {
CGPoint location = [gestureRecognizer locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
if ( indexPath.row != 0 ) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Cell Swipe"
message:@"Cell in row not equal to 0 swiped"
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:@"OK", nil];
[alert show];
[alert release];
}
}
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
CGPoint location = [touch locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
return indexPath.row != 0;
}
Зачем проходить через проблему распознавателя жестов, когда вы можете просто показать предупреждение через caneditrowatindexpath. Единственная проблема, которую я вижу, - если вы также используете кнопку редактирования - тогда вы получите много предупреждений одновременно.
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
return YES;
} else {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Info" message:@"You can only delete starting from the top cell" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
}
}
Если вы настроили использование распознавателя жестов, вам просто нужно использовать reloadRowsAtIndexPaths:withRowAnimation: для индекса 0 после удаления, это сбросит первую ячейку. Тем не менее, ваш cellforrowatindexpath настроен неправильно в вашем исходном посте и приведет к странным вещам для этой настройки в любом случае.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
BetCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BetCell"];
if ( !cell ) //this is needed in case a cell was never created in the first place
cell = [[[BetCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"BetCell"] autorelease];
Bet *bet = [self.bets objectAtIndex:([self.bets count]-indexPath.row-1)];
cell.BFNeedLabel.text = bet.BFNeeded;
if (indexPath.row != 0) {
UISwipeGestureRecognizer *swipeRecognizer = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeDetected:)];
swipeRecognizer.direction = (UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight);
[cell addGestureRecognizer:swipeRecognizer];
} else {//this is needed to reset a cell that is being reused (such as when you scroll off the page and return)
for (UIGestureRecognizer *gesture in cell.gestureRecognizers) {
[cell removeGestureRecognizer:gesture];
}
}
return cell;
}