2012-04-18 4 views
4

У меня есть список людей, которые занимают места. Я хочу, чтобы пользователь мог перегруппировать этих людей в разные места, однако некоторые пятна не работают. Я думал, что это будет наиболее легко реализовано с использованием возможностей перестановки UITableView. Однако я не могу понять, как держать мои недоступные пятна неподвижными.При перемещении ячеек в UITableView, как сделать ячейку неподвижной?

Например, я хочу переместить Activia Boulanger на место 5. Серые клетки должны быть неподвижными.

Начинающему вид:

Beginning

Что UITableView делает автоматически:

What UITableView does

То, что я хочу сделать UITableView:

What I want

Установка tableView:canMoveRowAtIndexPath:, по-видимому, просто мешает вам перемещать ячейку, но не препятствует движению клетки в реакции на движения других ячеек.

Любая помощь была бы принята с благодарностью. Благодаря


UPDATE: Ниже приведен пример кода с установкой для этой проблемы. Я не включил свои усилия в решение, потому что все они потерпели неудачу, и все это загромождает.

#import "LDYViewController.h" 

static NSString * unmoveableCellId = @"NoMove"; 
static NSString * moveableCellId = @"OkMove"; 

@implementation LDYViewController 
@synthesize tableView; 
@synthesize peopleList; 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    peopleList = [[NSMutableArray alloc] initWithObjects: 
        @"Belinda Boomer", @"Activia Boulanger", @"Arnold Carter", [NSNull null], @"Attila Creighton", [NSNull null], @"Bruce Cleary", [NSNull null], nil]; 
    [tableView setEditing:YES]; 
    // Do any additional setup after loading the view, typically from a nib. 
} 

#pragma mark - Table view data source 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    return 1; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    return peopleList.count; 
} 

- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell; 

    if([peopleList objectAtIndex:indexPath.row] == [NSNull null]) { 
     cell = [tableView dequeueReusableCellWithIdentifier:unmoveableCellId]; 
     if (cell == nil) { 
      cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:unmoveableCellId]; 
      cell.userInteractionEnabled = NO; 
      cell.contentView.backgroundColor = [UIColor grayColor]; 
     } 
    } else { 
     cell = [tableView dequeueReusableCellWithIdentifier:moveableCellId]; 
     if (cell == nil) { 
      cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:moveableCellId]; 
      NSString * name = [peopleList objectAtIndex:indexPath.row]; 
      cell.textLabel.text = name; 
     }   
    } 

    return cell; 
} 

- (void) tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath { 
} 

- (NSIndexPath *)tableView:(UITableView *)tableView 
targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath 
     toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath { 
    return proposedDestinationIndexPath; 
} 

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    if([peopleList objectAtIndex:indexPath.row] == [NSNull null]) { 
     return NO; 
    } 

    return YES; 
}  
@end 
+0

Как вы представляете пробелы в массиве людей? в массиве datasource, который поддерживает эту таблицу. – danh

+0

Это нулевые записи: [NSNull null].Когда я сталкиваюсь с пустой записью, я создаю тип «unmoveable». – LDY

+0

После перемещения вы можете просто изменить порядок своего массива, чтобы переместить нули обратно в позиции 3, 5, 7 и т. Д.? – danh

ответ

2

ли нормальный переставить логику на вашей модели, а затем, когда это будет сделано, положить аннулирует обратно туда, где вы хочу их. Введенный код не включает модель, поэтому вот примерная модель:

// always leave our array with a null at indexes 3,5,7 
// i'm sure you have better logic about where nulls go, but just to illustrate 
- (void)addNulls { 

    NSMutableArray *answer = [NSMutableArray array]; 
    for (id object in self.peopleList) { 
     if (![object isKindOfClass:[NSNull self]]) { 
      [answer addObject:object]; 
     } 
    } 

    assert(answer.count >= 4); 
    [answer insertObject:[NSNull null] atIndex:3]; 
    [answer insertObject:[NSNull null] atIndex:5]; 
    [answer insertObject:[NSNull null] atIndex:7]; 
    self.peopleList = answer; 
} 

// build a pretend model with nulls 
- (NSMutableArray *)peopleList { 

    if (!_peopleList) { 
     _peopleList = [NSMutableArray array]; 
     [_peopleList addObject:@"Moe"]; 
     [_peopleList addObject:@"Larry"]; 
     [_peopleList addObject:@"Curly"]; 
     [_peopleList addObject:[NSNull null]]; 
     [_peopleList addObject:@"Groucho"]; 
     [_peopleList addObject:[NSNull null]]; 
     [_peopleList addObject:@"Chico"]; 
     [_peopleList addObject:[NSNull null]]; 
     [_peopleList addObject:@"Harpo"]; 
    } 
    return _peopleList; 
} 



// normal rearrange logic, then fix your array up 
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { 

    // reorder the list with the typical logic, ignoring nulls 
    NSString *stringToMove = [self.peopleList objectAtIndex:fromIndexPath.row]; 
    [self.peopleList removeObjectAtIndex:fromIndexPath.row]; 
    [self.peopleList insertObject:stringToMove atIndex:toIndexPath.row]; 

    // now put nulls into the positions you want them 
    [self addNulls]; 
    [self.tableView reloadData]; 
} 
+0

По какой-то причине данные перезагрузки, кажется, возвращают все, где было первоначально, а не там, где указана модель. Я дважды проверил полученную модель, и все в порядке. Ведет ли ты себя по-другому? Спасибо за вашу помощь. – LDY

+0

Я проверил этот код в своей собственной таблице vc, и он работал правильно. Модель, не меняющаяся, свидетельствует о том, что moveRowAtIndexPath не работает или не вызван. Попробуйте поставить там точку останова и изучить модель до и после. – danh

+0

Я понял, в чем моя проблема. Это было очень глупо: когда я перерисовывал ячейки, я вложил свои назначения имен при тестировании нулевой ячейки, так как ячейка в строке x уже существовала, она не переписывала имена. Спасибо за ваше терпение! Теперь, если бы я мог сделать это, чтобы серые полосы не скользили во время анимации. Есть идеи для этого? :) – LDY

0

Вы можете сделать это с помощью:

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath{ 

В этом методе вы должны проверить с indexIndexPath и toIndexPath, чтобы проверить, если пользователь переходит на неверном месте. Измените источник данных tableview, чтобы вернуть ячейку или переместить ее в правильное положение.

+0

Я попробовал. Если бы я попытался переместить Activia в позицию 4, я изменил значение toIndexPath на позицию 5. Однако это только закончило перемещение ячеек 4 и 5, как если бы они были одним блоком, что привело к тем же позициям, что и изображение 2. – LDY

+0

Фактически, я думаю, я, возможно, неправильно понял ваш ответ. Я попробую. – LDY

+0

Я пробовал модифицировать источник данных, чтобы соответствовать виду, которое я бы хотел. Даже после перезагрузки таблицы это, похоже, не помогает. Я посмотрел '[UITableView reloadData]', и он говорит, что «он не должен вызываться в методах, которые вставляют или удаляют строки». Может быть, поэтому перезагрузка не сработала? Я только что добавил код к вопросу. Спасибо за вашу помощь. – LDY

8

Попробуйте это:

- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath*)sourceIndexPath 
     toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath 

Вы можете проверить proposedDestinationIndexPath, если вы не хотите, чтобы переместить строку к нему, вы можете вернуть sourceIndexPath то грести будет перемещен назад, в противном случае возвращает proposedDestinationIndexPath.

+0

В приведенном выше примере индекс 5 является допустимым местом для ячейки, однако мои серые ячейки все еще перемещаются. Эта проблема заключается не столько в том, что я могу переместить ячейку туда, где находится моя серая клетка, а в том, что серые клетки движутся в реакции на движения других клеток. Я пробовал что-то похожее на это: если я попытаюсь переместить ячейку туда, где есть серая ячейка, я увеличиваю строку, чтобы я был вынужден переместить ячейку ниже. Это мешает мне перемещать ячейки в индекс 4 (где находится серая ячейка), но серая ячейка все еще перемещается вместе со всеми другими ячейками, и я все еще получаю изображение 2. – LDY

+0

Тогда я думаю, что все предложения здесь в этой теме вам не поможет, вам нужно попробовать что-то вроде: - Разделить пятна на 3 группы (утром, днем, вечером), каждая группа будет разделом в вашем столе. - Каждая группа будет иметь фиксированное количество пятен, а затем, когда вы перемещаете элемент из раздела в другой, во-первых, проверьте, чтобы переместить элемент, который должен иметь перемещенный элемент. :) –

2

Я столкнулся с подобной проблемой и решил ее.

создать 2 раздела и поместить все серые цвета строк в разделе 2.

-(NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath{ 

if (proposedDestinationIndexPath.section == 1) 
    return sourceIndexPath; 
else 
    return proposedDestinationIndexPath; 

}

+1

Не будет ли эта группа всех моих серых клеток вместе? – LDY

+0

Работал идеально для меня! Спасибо – DocAsh59

Смежные вопросы