Пользовательский порядок UITableView - PullRequest
7 голосов
/ 25 октября 2010

Мне интересно, есть ли у кого-нибудь ссылка на хороший учебник или он может указать мне правильное направление для воссоздания ячеек «перетаскивания» в UITableView, таком как Epic Win App. Основная идея заключается в том, что вы нажимаете и удерживаете элемент списка, а затем перетаскиваете его туда, где вы хотите, чтобы этот элемент находился. Любая помощь будет принята с благодарностью.

Ответы [ 3 ]

13 голосов
/ 01 марта 2012

Самый простой способ, используя встроенные методы, выглядит следующим образом:

Во-первых, установите ячейку таблицы так, чтобы показывать управление переупорядочением. Простейший пример (с использованием ARC):

Предполагается, что NSMutableArray *things было создано где-то еще в этом классе

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"do not leak me"];
    if (!cell) {
        cell = [[UITableViewCell alloc] init];
        cell.showsReorderControl = YES;
    }
    cell.textLabel.text = [things objectAtIndex:indexPath.row];
    return cell;
}

Реализуйте свои два UITableViewDelegate метода, например:

Этот метод сообщает tableView, что он может быть переупорядочен

-(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
    return YES;
}

Вот где на самом деле происходит переупорядочение tableView

-(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {
    id thing = [things objectAtIndex:sourceIndexPath.row];
    [things removeObjectAtIndex:sourceIndexPath.row];
    [things insertObject:thing atIndex:destinationIndexPath.row];

}

и затем как-то где-то установите для редактирования значение true. Это один из примеров того, как вы можете сделать это. TableView должен быть в режиме редактирования для его переупорядочения.

- (IBAction)doSomething:(id)sender {
    self.table.editing = YES;
}

Надежда, которая служит конкретным примером.

7 голосов
/ 25 октября 2010

Это довольно просто - вероятно, поэтому нет явного учебника по этому вопросу.

Просто создайте UITableView обычным образом, но установите showsReorderControl каждой ячейки на TRUE.Когда вы переходите в режим редактирования (обычно нажатием кнопки «Редактировать» и установкой значения «Редактирование» UITableView в значение ИСТИНА) - в ячейках появятся полосы изменения порядка.

Примечание:

Если ваш источник данных реализует tableView:canMoveRowAtIndexPath: - и возвращает «НЕТ» - полосы переупорядочения не появятся.

Вам также необходимо будет внедрить –tableView:moveRowAtIndexPath:toIndexPath: в делегате источника данных.

4 голосов
/ 22 сентября 2015

Это решение здесь будет работать аналогично приложению «Напоминания» в OSX, которое позволяет изменять порядок ячеек, удерживая и перетаскивая их в любом месте.

Я создал подкласс UITableView, который позволяет перетаскивать и изменять порядок ячеек без необходимости использовать editing или использовать стандартные маркеры изменения порядка.

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

class ReorderTableView: UITableView {

var customView:UIImageView?
var oldIndexPath:NSIndexPath?

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    guard let touch1 = touches.first else{
        return
    }

    oldIndexPath = self.indexPathForRowAtPoint(touch1.locationInView(self))
    guard (oldIndexPath != nil) else{
        return
    }
    let oldCell = self.cellForRowAtIndexPath(self.oldIndexPath!)

    customView = UIImageView(frame: CGRectMake(0, touch1.locationInView(self).y - 20, self.frame.width, 40))
    customView?.image = screenShotView(oldCell!)
    customView?.layer.shadowColor = UIColor.blackColor().CGColor
    customView?.layer.shadowOpacity = 0.5
    customView?.layer.shadowOffset = CGSizeMake(1, 1)

    self.addSubview(customView!)
    oldCell?.alpha = 0
}

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {

    guard let touch1 = touches.first else{
        return
    }
    let newIndexPath = self.indexPathForRowAtPoint(touch1.locationInView(self))
    guard newIndexPath != nil else{
        return
    }
    guard oldIndexPath != nil else{
        return
    }
    if newIndexPath != oldIndexPath{
        self.moveRowAtIndexPath(oldIndexPath!, toIndexPath: newIndexPath!)
        oldIndexPath = newIndexPath
        self.cellForRowAtIndexPath(self.oldIndexPath!)!.alpha = 0
    }
    self.customView!.frame.origin = CGPointMake(0, touch1.locationInView(self).y - 20)
}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    self.customView?.removeFromSuperview()
    self.customView = nil
    guard (oldIndexPath != nil) else{
        return
    }
    self.cellForRowAtIndexPath(self.oldIndexPath!)!.alpha = 1
}

func screenShotView(view: UIView) -> UIImage? {

    let rect = view.bounds
    UIGraphicsBeginImageContextWithOptions(rect.size,true,0.0)
    let context = UIGraphicsGetCurrentContext()

    CGContextTranslateCTM(context, 0, -view.frame.origin.y);
    self.layer.renderInContext(context!)
    let capturedImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return capturedImage
}

}

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

Обновление:

Некоторые замечания, которые я нашел.Очень важно, чтобы вы выяснили, как вы хотите использовать прокрутку, и измените ее соответствующим образом.Например, когда я его смоделировал, я установил scrollingEnabled = false.. В долгосрочной перспективе мне захотелось прокручивать, поэтому я изменил код, чтобы запускать эту функцию только при печати длиннее 0,25 (для этого я использовал некоторые таймеры).Затем я временно отключил бы прокрутку в течение этого периода и снова включил бы ее по завершении.

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