Как я могу обновить UITableView, пока пользователь реорганизует ячейки? - PullRequest
2 голосов
/ 01 сентября 2011

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

enter image description here

Чтобы добиться такого взгляда, я должен был установить backgroundView каждого UITableViewCell.Верхнее и нижнее изображения используют отдельное изображение, а не посередине.

ОБНОВЛЕНО :

Я не уверен, что пропускаю какие-либо случаи, потому что изображениявсе еще запутались при повторном заказе.

for (NSIndexPath* visibleIndexPath in tableView.indexPathsForVisibleRows) {
        UITableViewCell* cell = [tableView cellForRowAtIndexPath:visibleIndexPath];

        //Top moving to middle rows
        if (sourceIndexPath.row == 0 && proposedDestinationIndexPath.row != sectionRows - 1) {
            ((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tablemiddle55@2x.png"];
        }
        //Top moving to bottom
        else if (sourceIndexPath.row == 0 && proposedDestinationIndexPath.row == sectionRows - 1) {
            ((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tablebottom55@2x.png"];
        }
        //Top moving to top
        else if (sourceIndexPath.row == 0 && proposedDestinationIndexPath.row == 0) {
            ((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tabletop55@2x.png"];
        }
        //Middle moving to top
        else if (sourceIndexPath.row != 0 && sourceIndexPath.row != sectionRows -1 && proposedDestinationIndexPath.row == 0)
        {
            ((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tabletop55@2x.png"];
        }
        //Middle moving to bottom
        else if (sourceIndexPath.row != 0 && sourceIndexPath.row != sectionRows -1 && proposedDestinationIndexPath.row == sectionRows - 1)
        {
            ((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tablebottom55@2x.png"];
        }
        //Middle moving to middle
        else if (sourceIndexPath.row != 0 && sourceIndexPath.row != sectionRows -1 && 
                 proposedDestinationIndexPath.row != sectionRows -1 && proposedDestinationIndexPath.row !=0)
        {
            ((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tablemiddle55@2x.png"];
        }
        //Bottom moving to top
        else if (sourceIndexPath.row == sectionRows - 1 && proposedDestinationIndexPath.row == 0)
        {
            ((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tabletop@2x.png"];
        }
        //Bottom moving to middle
        else if (sourceIndexPath.row == sectionRows - 1 && proposedDestinationIndexPath.row != 0 && proposedDestinationIndexPath.row != sectionRows - 1)
        {
            ((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tablemiddle@2x.png"];
        }
        //Bottom moving to bottom
        else if (sourceIndexPath.row == sectionRows - 1 && proposedDestinationIndexPath.row == sectionRows - 1)
        {
            ((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tablebottom@2x.png"];
        }
    }

Ответы [ 3 ]

3 голосов
/ 01 сентября 2011

Ну, вам просто нужно изменить фоновые изображения ячеек, которые изменились так же, как вы сделали в tableview:cellForRowAtIndexPath:.

- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath {
   //The rest of your stuff you need to do

   for (NSIndexPath* visibleIndexPath in self.tableView.indexPathsForVisibleRows) {
       UITableViewCell* visibleCell [self.tableView cellForRowAtIndexPath:visibleIndexPath];
       if (visibleIndexPath.row == 0) ((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tabletop55.png"];
       else if (visibleIndexPath.row == [self tableView:tableView numberOfRowsInSection:visibleIndexPath.section) {
           ((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tablebottom55.png"];
       }
       else ((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tablemiddile55.png"];
   }
}
1 голос
/ 06 сентября 2011

Код, который вы разместили, в основном неверен из-за for {}.В нынешнем виде вы делаете что-то вроде «если место назначения таково, а источник таков, измените все видимые в данный момент ячейки».Но в любом случае, это не главная проблема.

Должен сказать, я много раз играл с методом tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:, даже не пытаясь ответить на этот вопрос.Теперь я чувствую себя более уверенно, чтобы написать это.

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

Например, предположим, что у вас естьячейка с индексом 0 с заголовком @"Hello" и следующая ячейка с @"World", если вы начнете перетаскивать первую ячейку вниз, анимация переместит ячейку «Hello» на одну строку вверх, но вызовет tableView:cellForRowAtIndexPath длястрока с индексом 0 всегда будет возвращать ячейку «Hello».TableView остается неизменным до тех пор, пока не закончится переупорядочение tableView, а все остальное - просто конфетка.

Итак, чтобы ответить на ваш вопрос и поменять изображения на лету (как только пользователь переместит ячейку),Вы должны сделать следующее, например, для первой строки:

//Top moving to middle rows
if (sourceIndexPath.row == 0 && proposedDestinationIndexPath.row != 0)
{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:sourceIndexPath.section]];
    ((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tablemiddle55"];
}

Когда пользователь перетаскивает строку 0 вниз, он указывает строке на 1 поменять местами фон, так как он станетновый верхний ряд.Аналогичные случаи должны быть рассмотрены для нижнего ряда, или средний ряд становится первым.Кроме того, for {} с видимыми ячейками в этом случае не требуется.

Редактировать: Хорошо, мне удалось сделать ВСЕ случаи, здесь есть кое-какие странные вещи,но это работает большую часть времени.Код здесь просто меняет detailLabel на «First» / «Middle» / «Last», но это легко изменить с помощью Find & Replace.

- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
    //NSLog(@"%d -> %d (proposed)", sourceIndexPath.row, proposedDestinationIndexPath.row);

    NSInteger lastRow = [arrayWithContent count]-1;

    // Adjust the row being moved
    if (proposedDestinationIndexPath.row == 0)
        [tableView cellForRowAtIndexPath:sourceIndexPath].detailTextLabel.text = @"First";
    else if (proposedDestinationIndexPath.row == lastRow)
        [tableView cellForRowAtIndexPath:sourceIndexPath].detailTextLabel.text = @"Last";
    else
        [tableView cellForRowAtIndexPath:sourceIndexPath].detailTextLabel.text = @"Middle";

    // Top -> Middle
    if (sourceIndexPath.row == 0 && proposedDestinationIndexPath.row == 1)
    {
        NSLog(@"Top -> Middle");
        [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]].detailTextLabel.text = @"First";
    }
    // Top -> Top (user is screwing around)
    else if (sourceIndexPath.row == 0 && proposedDestinationIndexPath.row == 0)
    {
        NSLog(@"Top -> Top");
        [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]].detailTextLabel.text = @"Middle";
    }
    // Middle -> Top
    else if (sourceIndexPath.row > 0 && proposedDestinationIndexPath.row == 0)
    {
        NSLog(@"Middle -> Top");
        [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]].detailTextLabel.text = @"Middle";
    }
    // Middle -> Bottom
    else if (sourceIndexPath.row < lastRow && proposedDestinationIndexPath.row == lastRow)
    {
        NSLog(@"Middle -> Bottom");
        [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:lastRow inSection:0]].detailTextLabel.text = @"Middle";
    }
    // Bottom -> Middle
    else if (sourceIndexPath.row == lastRow && proposedDestinationIndexPath.row == lastRow-1)
    {
        NSLog(@"Bottom -> Middle");
        [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:(lastRow-1) inSection:0]].detailTextLabel.text = @"Last";
    }
    // Bottom -> Bottom (user is screwing around, AGAIN)
    else if (sourceIndexPath.row == lastRow && proposedDestinationIndexPath.row == lastRow)
    {
        NSLog(@"Bottom -> Bottom");
        [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:(lastRow-1) inSection:0]].detailTextLabel.text = @"Middle";
    }
    // Middle -> Top -> Middle (ugh)
    else if (sourceIndexPath.row > 0 && sourceIndexPath.row < lastRow && proposedDestinationIndexPath.row == 1)
    {
        NSLog(@"Middle -> Top -> Middle");
        [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]].detailTextLabel.text = @"First";
    }
    // Middle -> Bottom -> Middle (ugh x2)
    else if (sourceIndexPath.row > 0 && sourceIndexPath.row < lastRow && proposedDestinationIndexPath.row == lastRow-1)
    {
        NSLog(@"Middle -> Bottom -> Middle");
        [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:lastRow inSection:0]].detailTextLabel.text = @"Last";
    }

    return proposedDestinationIndexPath;
}
0 голосов
/ 05 сентября 2011

Вы должны обновлять массив данных, когда пользователь его редактирует.После обновления нового массива вы можете вызвать reloadData, чтобы обновить UITableView.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...