использование scrollViewWillEndDragging, чтобы гарантировать, что UIScrollView останавливается с определенным шагом

Я хотел бы, чтобы мой UIScrollView естественным образом скользил к окончаниям при определенных добавочных значениях, соответствующих каждым 50 точкам ширины горизонтально прокручиваемого UIScrollView. Для этого я настроил scrollViewWillEndDragging вот так (как рекомендуется, но подробно не описано в ответе здесь Прокрутка горизонтального UIScrollView с пошаговым шагом?):

- (void) scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{

    if(fmodf(targetContentOffset->x, 50.0)){
        int roundingNumber1 = 50;
        CGFloat newOffset = roundingNumber1 * floor(((scrollView.contentOffset.x)/roundingNumber1)+0.5);
        targetContentOffset->x = newOffset;
    }

}

Однако я не уверен, что это на самом деле останавливает представление с определенным шагом, и я также замечаю, что эффект асимметричен. Хотя мои движения прокрутки/скорость/и т. д. одинаковы, прокрутка вправо намного менее плавна, чем прокрутка влево. Прокрутка вправо останавливается быстрее и резче. здесь есть видео. Почему это поведение асимметрично и как его изменить?

Причина, по которой я думаю, что прокрутка не останавливается с шагом 50, заключается в том, что у меня также есть UILabel под представлением прокрутки, которое обновляется другими функциями делегата, чтобы показать смещение. Показываемое значение редко приближается к 50 при прокрутке. Это потому, что прокрутка не увеличивается до значений 50 или потому что я не обновляюсь в нужное время?

Спасибо за любой совет.

- (void) scrollViewDidScroll:(UIScrollView *)scrollView{

    if(abs(self.lastOffset - scrollView.contentOffset.x) > 49){
        CGFloat newNumber = scrollView.contentOffset.x;
        self.numberProperty.text = [NSString stringWithFormat:@"%.00f", scrollView.contentOffset.x];
        self.lastOffset = scrollView.contentOffset.x;
        [self.view setNeedsDisplay];
    }
}

- (void) scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{
            self.numberProperty.text = [NSString stringWithFormat:@"%.00f", scrollView.contentOffset.x];
}

person sunny    schedule 23.07.2015    source источник
comment
В вашем методе делегирования - (void) scrollViewWillEndDragging: (UIScrollView *) scrollView withVelocity: (CGPoint) скорость targetContentOffset: (inout CGPoint *) targetContentOffset замените 'contentOffset' на '* targetContentOffset' в новом расчете целевого смещения.   -  person MiKL    schedule 25.07.2015


Ответы (1)


Вместо реализации этих методов делегата вы можете установить pagingEnabled в представлении прокрутки значение true, чтобы получить это поведение бесплатно. Когда пейджинг включен, прокрутка автоматически привязывается к ближайшей «странице», когда вы заканчиваете перетаскивание, где ширина страницы равна ширине прокрутки.

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

  1. Сделайте так, чтобы ваш вид прокрутки имел ту же ширину, что и один из ваших элементов (50,0 единиц в вашем случае).
  2. Установите для scrollView.clipsToBounds значение false, чтобы представление прокрутки рисовало подпредставления за пределами его гораздо меньших границ.
  3. Установите для scrollView.pagingEnabled значение true, чтобы представление прокрутки прокручивалось с пейджингом.

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

  1. Создайте класс «сенсорная переадресация» и добавьте его в свое представление.

Этот класс принимает все получаемые события касания и вместо этого отправляет их в свое свойство targetView. DJK — это случайный префикс, который я придумал для названия класса.

@interface DJKTouchForwardingView : UIView

/** The view to which touch events should be forwarded. */
@property (weak, nonatomic) UIView *targetView;

@end

@implementation DJKTouchForwardingView

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView *child = nil;
    if ((child = [super hitTest:point withEvent:event]) == self) {
        return self.targetView;
    }
    return child;
}

@end
  1. Сделайте представление прокрутки подвидом представления сенсорной переадресации и назначьте его свойству targetView.

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

person Dklionsk    schedule 25.07.2015