Учебное пособие по перетаскиванию и перетащить элемент из UITableView в UITableView [закрыто]

Я какое-то время стучал по нему головой и понял это. Я хочу вернуть сообществу, так как я получил большую помощь от этого сайта:).

Я ' я пытаюсь скопировать элемент из одного UITableView в другой UITableView, и информация, которую я видел в Интернете относительно того, как это сделать, была в лучшем случае отрывочной. Я понял это сам, поэтому опишу свою маленькую архитектуру.

  • Master UIView
    • UIView с UITableView
      • Пользовательский UITableViewCell
        • Пользовательский UIView, который копируется (объект Person в моем случае)
    • UIView с UITableView
      • Пользовательский UITableViewCell
        • Пользовательский UIView, который копируется (объект Person в моем случае)

Объект person, который у меня есть в UITableView, - это объект, который я хочу перетащить из одной таблицы в другую. Мне было сложнее всего понять, как вынуть предмет из стола и перетащить его одним плавным движением. Дольше всего мне потребовалось бы два прикосновения для выполнения операции.

Начиная с объекта Person, это простой объект, содержащий изображение. Мне пришлось реализовать свой собственный метод touchesMoved, чтобы изменить центральную позицию Person, когда происходит перетаскивание.

-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    if( m_moveable == YES ){
        UITouch *touch = [touches anyObject];
        CGPoint location = [touch locationInView:self.superview];

        if( 0 < location.x-50 && location.x+50 < 768 ){ 
            if( 0 < location.y-50 && location.y+150 < 1004 ){
                self.center = location;
            }
        }
    }
}

Я установил флаг userInteractionEnabled объекта Person в значение NO при инициализации, чтобы любые щелчки в таблице не попадали в ловушку. Персона объект. В этом случае объект Person будет перемещаться в пределах таблицы, которая побеждает цель.

Следующий объект - мой пользовательский UITableViewCell. Этот объект отвечает за первое касание пользователя. То, что он должен сделать, это поймать это прикосновение и «вытолкнуть» Человека наружу. Person - это одно из подпредставлений, принадлежащих пользовательскому UITableViewCell.

 - (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UIView *parent = self.superview.superview.superview;    

    Person *s = nil;
    for( UIView *child in self.subviews ){
        if( [child isKindOfClass:[Person class]] ){
            s = child;
            s removeFromSuperview];
            break;
        }        
    }

    if( s != nil ){
        self.userInteractionEnabled = NO;
        s.userInteractionEnabled = YES;
        UITableView *subParent = self.superview;   //EDIT #1
        subParent.scrollEnabled = NO;              //EDIT #1

        [parent addSubview:s];
        //[self touchesEnded:touches withEvent:event]; //EDIT #1
    }
}

Важно отметить, что флаг userInteractionEnabled переворачивается в вышеуказанном методе. До прикосновения объект Person находится вне пределов касания человека. После того, как пользовательская ячейка перехватывает движение, Person освобождается, добавляя его в представление родителя, а затем активируется (userInteractionEnabled = YES). Затем объект Person «рождается» и может самостоятельно обрабатывать движения.

Это имеет один незначительный сбой в том, что объект Person мигает в верхнем левом углу, но затем сразу же падает на палец пользователя.

Последняя часть этого дизайна заключается в том, что мастер UIView должен обрабатывать «сенсорный переход». Когда пользователь касается таблицы и объект Person появляется, приложение должно понимать, что фокус должен быть удален из таблицы и направлен на объект Person. Способ, которым это было сделано, заключается в том, что метод hitTest в главном UIView был перегружен следующим образом.

- (UIView*) hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    UIView *rv = nil;
    for(UIView *child in self.subviews){
        if( [child isKindOfClass:[Person class]] ){
            rv = child;
            child.center = point;
            break;
        }
    }
    if( rv == nil ){
        rv = [super hitTest:point withEvent:event];
    }   
    return rv;
}

Этот код работает так, что, когда Person выталкивается из таблицы, он не имеет прикосновения сосредоточены на этом. Касание «принадлежит» UITableView, из которого выскочил человек. Метод hitTest является ключом к перефокусировке этого прикосновения. Регулярно система проверяет, какой UIView является фокусом касания. Метод hitTest вызывается системой для идентификации этого UIView. Когда Person присоединен к главному представлению, эта функция hitTest выполняет итерацию по всем подпредставлениям и обнаруживает присутствие Person и возвращает его как «доминирующий» объект, к которому прикоснулись. Любое движение вашего пальца будет немедленно сообщено лицу, а не UITableView.

Это внутренняя часть реализации. Чтобы UITableView «поймал» движущийся объект, теперь просто, и я оставлю это для вас, чтобы попробовать! Если у вас есть какие-либо вопросы, пожалуйста, напишите их!

РЕДАКТИРОВАТЬ # 1 Отбрасывание объекта Person оказывается сложнее, чем я думал :). Мне пришлось добавить строку, чтобы предотвратить прокрутку UITableView при перемещении родителя, потому что UITableView всасывает все события перемещения.
Функция touchesEnded запускается в пользовательском классе UITableViewCell.
MJ

47
задан Vadim Kotov 15 September 2017 в 15:26
поделиться

1 ответ

Привет, мне удалось создать перетаскивание строки в UITableView на другую строку той же таблицы. Я создал uiImageView, представляющий движущийся элемент (который не был удален из таблицы), и прикрепил его к самому переднему UIView, чтобы сделать его перетаскиваемым на весь экран. Вот несколько сообщений о проблемах, с которыми я столкнулся:

  1. UITableView: перетащите строку на другую
  2. UITableView: программную прокрутку представления содержимого
  3. UITableView: пользовательские жесты не позволяют прокручивать ее

Надеюсь, это поможет ^^

7
ответ дан 26 November 2019 в 19:57
поделиться