Как правильно пересылать события UITouch в цепочку респондента? - PullRequest
0 голосов
/ 29 июня 2010

Я борюсь со следующей проблемой.У меня есть контроллер представления с прокруткой.С этим видом прокрутки пользователь должен иметь возможность пролистывать множество «страниц» - как в приложении погоды Apple, так что нет ничего необычного.Тогда каждая «страница» в представлении прокрутки является табличным представлением, показывающим список элементов.И здесь я вхожу в проблемы.

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

Это поведение вызывает реальную проблему в моем случае (представление таблицы в представлении прокрутки), потому что представление таблицы является потомком представления прокрутки, и это представление, которое возвращаетсяпутем проверки попадания при нормальных обстоятельствах, что приводит к тому, что все события захватываются табличным представлением, поэтому его родительское представление прокрутки get никогда не вызывается, поэтому никакое считывание никогда не выполняется.

Естественно, когда я переопределяю hitTest: withEvent:метод в моем подклассе табличного представления и возвращает суперпредставление (представление прокрутки, фактически), ситуация противоположна - пользователь может пролистывать страницы, но не может прокручивать представление таблицы.

Так что мне нужно выяснить, этокак - на любом уровне - определить, какое действие хочет предпринять пользователь (проведите пальцем или прокрутитеble view), а затем передать поток событий соответствующему компоненту.

Я борюсь с этой проблемой пару дней назад, но не могу обойтись.Ниже то, что я закончил до сих пор.Здесь все очень просто.Он делает почти то, что мне нужно - за исключением того, что табличное представление никогда не прокручивается ... Обратите внимание, что мой подкласс табличного представления всегда возвращает self.superview, которое является представлением прокрутки.

/// UIViewController

- (void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event {

    [super touchesBegan: touches withEvent: event];

    /// Save initial touch location for later use
    _motionStart = [[touches anyObject] locationInView: self.scrollView];

    /// Save reference to initial event
    _initialEvent = event;

    /// Fire timer
    _gestureTimer = [NSTimer scheduledTimerWithTimeInterval: 0.2
                                 target:self selector:@selector(gestureTimer:)
                               userInfo: touches repeats: NO];
}

- (void) touchesMoved: (NSSet *) touches withEvent: (UIEvent *) event {

    if(!_gestureTimer && !_forwardingTouchesToTableView) {
    /// If no timer is running and no event forwarding is performed, pass to super
        [super touchesMoved: touches withEvent: event];
    }
    else {
        /// Pass event to currently visible tableview
        [self.scrollView.centerPage touchesMoved: touches withEvent: event];
    }

}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

    [super touchesEnded: touches withEvent: event];

    if(_forwardingTouchesToTableView) {
        [self.scrollView.centerPage touchesEnded: touches withEvent: event];
    }

    /// Reset state
    _motionStart = CGPointZero;

    _forwardingTouchesToTableView = NO;
}

- (void) gestureTimer: (NSTimer *) timer {

    _gestureTimer = nil;

    NSSet *touches = (NSSet *)timer.userInfo;   
    UITouch *touch = (UITouch *)[touches anyObject];

    CGPoint currentTouchLocation = [touch locationInView: self.scrollView];

    float deltaX = fabs(_motionStart.x - currentTouchLocation.x);
    float deltaY = fabs(_motionStart.y - currentTouchLocation.y);

    if(deltaY >= 4.0 && deltaX <= 12.0) {

        /// Vertical move, forward to tableview
        [self.scrollView cancelTouches];
        _forwardingTouchesToTableView = YES;
        [self.scrollView.centerPage touchesBegan: touches  withEvent: _initialEvent];
        _initialEvent = nil;
    }
    else {
        /// Horizontal swipe - just reset state
        _initialEvent = nil;
        _forwardingTouchesToTableView = NO;
    }
}

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

Спасибо за любые предложения.

1 Ответ

0 голосов
/ 29 июня 2010

То есть, в основном, вы хотите вертикальную прокрутку в табличном представлении, но подкачку для горизонтальных прокруток?

Если вы можете жить с совместимостью 3.2+ (на самом деле на iPhone 4.0), я бы попробовал: - придерживаться стандартных компонентов и не требует дополнительной обработки - используйте UISwipeGestureRecognizer и добавьте это в табличное представление - если сработает распознаватель жестов, то проверьте, является ли это горизонтальным пролистыванием, и если это так, программно перейдите на страницы

Конечно, вся концепция работает только в том случае, если не нужны жесты смахивания для ячеек - т.е. для удаления. Но это верно для всех подходов, конечно.

До версии 3.2 вам действительно нужно промокнуть руки сенсорными манипуляторами. Создание подклассов UITableView и переопределение штрихов: Beg: и т. Д., Я бы попробовал с первой попытки (и распознать горизонтальные пролистывания и вызвать пейджинг), хотя решение в целом ужасно

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