UITableView: программная прокрутка представления содержимого

Привет, я пытаюсь перенаправить прикосновения, которые я получаю от UIView, который находится перед UITableView. Но делает так, что я больше не могу прокручивать таблицу (см. здесь< /а>).

Итак, теперь я пытаюсь сделать прокрутку таблицы программно, и я смотрю на setContentOffset:animated: и scrollRectToVisible:animated: с успехом только с первым.
Вот мой код в классе, который является подклассом UITableView:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    NSLog(@"BEGTB");
    //previousXPan = 0.0;

    UITouch * touch = [touches anyObject];
    CGPoint tPoint = [touch locationInView:self]; 
    previousYPan = tPoint.y;

    [super touchesBegan:touches withEvent:event];
    //
    //[super touchesShouldBegin:touches withEvent:event inContentView:self];
    //[[self nextResponder] touchesBegan:touches withEvent:event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch * touch = [touches anyObject];
    CGPoint tPoint = [touch locationInView:self]; 


    NSLog(@"MOVTB");
    NSLog(@"BOUNDZ %f, %f, %f, %f", self.bounds.origin.x, self.bounds.origin.y, self.bounds.size.height, self.bounds.size.width);
    NSLog(@"CONTENT SIZE  %f, %f",  self.contentSize.height, self.contentSize.width);

    CGRect rc = [self bounds];
    NSLog(@"%f %f", rc.size.height, rc.size.width);
    CGRect newRect = CGRectMake(rc.origin.x, rc.origin.y + self.contentSize.height, self.contentSize.width, fabs(tPoint.y - previousYPan));
    NSLog(@"BOND RECT %f, %f, %f, %f", rc.origin.x, rc.origin.y, rc.size.height, rc.size.width);
    NSLog(@"NEW RECT %f, %f, %f, %f", newRect.origin.x, newRect.origin.y, newRect.size.height, newRect.size.width);
    //[self scrollRectToVisible:newRect animated:YES];
    NSLog(@"Content OFFSET %f",tPoint.y - previousYPan);
    [self setContentOffset:CGPointMake(rc.origin.x,(tPoint.y - previousYPan) *2.0 )animated:YES];
    previousYPan = tPoint.y;
    //[super touchesMoved:touches withEvent:event];
    //[[self nextResponder] touchesMoved:touches withEvent:event];
}

Но результат действительно тормозит и глючит. Любая лучшая идея?


person rano    schedule 11.08.2010    source источник
comment
Ваш UIView находится внутри uitableviewcell, что упростит задачу, просто заглянув внутрь конкретной ячейки и перенаправив касание?   -  person vodkhang    schedule 11.08.2010
comment
@vodkhang: мой UIView — это представление поверх табличного представления, и оно перенаправляет прикосновение к затронутой ячейке uitableview, которая перенаправляет в подходящее представление (код находится по ссылке в сообщении). Я помещаю этот UIView и не использую UITableViewCell напрямую, потому что я хочу создать ImageView, который будет перетаскиваться по всей области содержимого.   -  person rano    schedule 11.08.2010
comment
это может звучать глупо, но NSLOG сильно снижает производительность (особенно если используется в часто вызываемых методах, таких как cellForRowAtIndexPath и тому подобное). попробуйте удалить все вызовы журнала и посмотрите, станет ли он лучше, прежде чем углубляться в него.   -  person samsam    schedule 11.08.2010
comment
@samsam: ничего, даже комментировать все это. производительность не такая уж проблема, но все это глючит и странно, оно подпрыгивает вверх и вниз и иногда кажется, что оно не двигается, иногда оно взлетает как ракета   -  person rano    schedule 11.08.2010
comment
хммм, тогда может помочь посмотреть, как часто запускается touchesMoved, и, возможно, ограничить вызовы setContentOffset или, по крайней мере, найти способ позволить setContentOffset полностью анимировать перед повторным вызовом setcontentOffset (или, может быть, попробовать с помощью анимированный: НЕТ) это все, о чем я могу думать в данный момент. ваше здоровье!   -  person samsam    schedule 12.08.2010
comment
@samsam: ниже я разместил решение   -  person rano    schedule 17.08.2010
comment
очень красиво! Попробую в ближайшее время :)   -  person samsam    schedule 17.08.2010


Ответы (1)


Я почти нашел подходящее решение (это не похоже на обычную прокрутку, но...).

Сначала я определяю максимальное и минимальное количество пикселей в области содержимого табличного представления по оси Y (высота contentSize когда представление полностью загружено).

Я проверяю движение, сделанное постепенно, но не ссылаясь на положение касания в виде таблицы! Я должен проверить это на верхнем уровне UIView, который его покрывает, потому что, когда вы изменяете смещение содержимого таблицы, вы динамически меняете ее размеры, и вы можете получить эффект ускорения.

Вот код:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch * touch = [touches anyObject];

    CGPoint tPoint = [touch locationInView:[viewController draggableAreaView]];



    CGRect rc = [self bounds];


    float totalOS = tPoint.y - previousYPan;
    if ((contentOffSetY >= minY && contentOffSetY <= maxY) ||
        (contentOffSetY < minY - 5 && totalOS < 0) ||
        (contentOffSetY > maxY + 5 && totalOS > 0))
    {

        if (totalOS > 0)
            totalOS += OFFSET;
        else if (totalOS < 0)
            totalOS -= OFFSET;
        [self setContentOffset:CGPointMake(rc.origin.x,self.contentOffset.y + totalOS)animated:NO];

    }
    else /*if (contentOffSetY < minY - 5 && totalOS < 0) */
    {
        [self resetOffset];
    }
    previousYPan = tPoint.y; 

}

- (void)resetOffset{

    CGRect rc = [self bounds];
    if(contentOffSetY < minY)
    {
        [self setContentOffset:CGPointMake(rc.origin.x, minY + 50)animated:YES];
    }
    else if (contentOffSetY > maxY)
    {
        [self setContentOffset:CGPointMake(rc.origin.x, maxY - 50)animated:YES];
    }
}

Еще несколько советов:

  • здесь draggableAreaView - это верхний UIView, из которого я получаю "абсолютную" позицию
  • OFFSET — это константа, определяемая для линейного увеличения скорости прокрутки (без нее touchesMoved: , вызываемая много раз, каждый раз дает относительное перемещение всего на один пиксель)
  • , minY и maxY — предварительно рассчитанные предельные значения (для их вычисления я рассчитал высоту всех ячеек в таблице для максимума и высоту видимого содержимого для минимума)
  • Я добавил смещение к minY и maxY, чтобы анимация была более заметной.
person rano    schedule 17.08.2010
comment
можете ли вы сказать мне, что такое minY, maxY и contentOffSetY?? я думаю, что моя проблема похожа на эту проблему - person R. Dewi; 12.01.2011