Размер страницы UITableView при включенном разбиении на страницы

Я столкнулся с простой, но утомительной проблемой. Я пытаюсь сделать UITableView для страницы, как UIScrollView, но включение разбиения на страницы мне не очень помогает, потому что я не могу установить размер страницы, поэтому tableview прокручивается точно по ее высоте, поэтому он показывает строки 1 ... 10 или 11 ... 20 и так далее. Вместо этого я бы хотел, чтобы ни одна ячейка не оставалась обрезанной над или под представлением при прокрутке (то есть разбиении по страницам) без фиксированного диапазона отображаемых ячеек.

Большое спасибо


person maxcanna    schedule 25.02.2010    source источник


Ответы (5)


Проще и эффективнее :)

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{

    if(decelerate) return;

    [self scrollViewDidEndDecelerating:scrollView];
}


- (void)scrollViewDidEndDecelerating:(UITableView *)tableView {

    [tableView scrollToRowAtIndexPath:[tableView indexPathForRowAtPoint: CGPointMake(tableView.contentOffset.x, tableView.contentOffset.y+tableView.rowHeight/2)] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
person PRCode    schedule 01.08.2012
comment
Это решение отлично сработало для меня и работало для каждого свитка. Другое решение было немного несовместимым с его результатами ... иногда оно цеплялось за верх ячейки, иногда нет. - person codeqi; 04.06.2013
comment
@codeqi причина, по которой он иногда прыгает наверх, заключается в том, что у вас, вероятно, есть пробел между вашими элементами в CollectioView. В этом случае метод indexPathForRowAtPoint вернет 0,0 - что приведет к вершине. ;) - person Lirik; 02.03.2014

Просто, но эффективно:

    - (void)scrollViewDidEndDecelerating:(UITableView *)tableView {
            int tomove = ((int)tableView.contentOffset.y%(int)tableView.rowHeight);
            if(tomove < tableView.rowHeight/2) [tableView setContentOffset:CGPointMake(0, tableView.contentOffset.y-tomove) animated:YES];
            else [tableView setContentOffset:CGPointMake(0, tableView.contentOffset.y+(tableView.rowHeight-tomove)) animated:YES];
    }

    - (void)scrollViewDidEndDragging:(UITableView *)scrollView willDecelerate:(BOOL)decelerate {
            if(decelerate) return;

            [self scrollViewDidEndDecelerating:scrollView];
    }
person maxcanna    schedule 26.02.2010
comment
На самом деле не работает для меня. Кроме того, поскольку вы используете DidEndDecelerating, код не вызывается, когда нет замедления (например, если таблица не щелкает, а мягко отпускается) - person pixelfreak; 01.07.2011
comment
Таким образом, вы должны добавить тот же код в - (void) scrollViewDidEndDragging: (UIScrollView *) scrollView willDecelerate: (BOOL) decelerate, если willDecelerate: (BOOL) decelerate - false - person Julien; 18.10.2011
comment
@Julien Ага, я забыл вставить второй метод. Никто не замечал этого больше года! Спасибо - person maxcanna; 19.10.2011
comment
Прыгает каждая моя 4-я ячейка. Пагинация работает нормально для 1-го, 2-го и 3-го, но как только я пытаюсь прокрутить 4-й, он переходит к 5-му - person Tariq; 05.07.2012

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

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
                     withVelocity:(CGPoint)velocity
              targetContentOffset:(inout CGPoint *)targetContentOffset
{    
    CGFloat rowHeight = tableView.rowHeight;
    int verticalOffset = ((int)targetContentOffset->y % (int)rowHeight);
    if (velocity.y < 0)
    {
        targetContentOffset->y -= verticalOffset;
    }
    else if (velocity.y > 0)
    {
        targetContentOffset->y += (rowHeight - verticalOffset);
    }
    // No velocity, snap to closest page
    else
    {
        if (verticalOffset < rowHeight / 2)
        {
            targetContentOffset->y -= verticalOffset;
        }
        else
        {
            targetContentOffset->y += (rowHeight - verticalOffset);
        }
    }    
}

Обратите внимание, что дополнительно устанавливая

 self.tableView.decelerationRate = UIScrollViewDecelerationRateFast;

в viewDidLoad: приближает его к реальному, но не совсем.

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

person Ricardo Sanchez-Saez    schedule 08.07.2014

Это работает как настоящий пейджинг:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView 
                     withVelocity:(CGPoint)velocity
              targetContentOffset:(inout CGPoint *)targetContentOffset
{
    int tomove = ((int)targetContentOffset->y % (int)self.tableView.rowHeight);
    if(tomove < self.tableView.rowHeight/2)
        targetContentOffset->y -= tomove;
    else 
        targetContentOffset->y += (self.tableView.rowHeight-tomove);
}

и сделайте это в -viewDidLoad:

self.tableView.decelerationRate = UIScrollViewDecelerationRateFast;
person k06a    schedule 17.08.2013
comment
Это работает почти идеально, но не работает для полноэкранных ячеек, когда вы выполняете очень осторожный поворот (недостаточный для перемещения по странице). Он мгновенно перемещает ячейку назад, вместо того, чтобы плавно ее анимировать. - person Ricardo Sanchez-Saez; 08.07.2014

А в Swift ...

func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    if !decelerate {
        self.scrollViewDidEndDecelerating(scrollView)
    }
}

func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
    if let indexPathToScrollTo: NSIndexPath = self.tableView.indexPathForRowAtPoint(CGPointMake(self.tableView.contentOffset.x, self.tableView.contentOffset.y+tableView.rowHeight/2)) {
        self.tableView.scrollToRowAtIndexPath(indexPathToScrollTo, atScrollPosition: UITableViewScrollPosition.Top, animated: true)
    }
}
person villy393    schedule 30.06.2015