IOS. Как расширить область реагирования на события прокрутки UIScrollView?

У меня включена страница UIScrollView и настроен clipToBounds = NO, чтобы я мог видеть за пределами текущей страницы.

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

Как я могу это реализовать?

Постскриптум Согласно документации Apple (https://developer.apple.com/documentation/uikit/uiscrollview), если значение свойства pagingEnabled равно YES, представление прокрутки останавливается на кратных границах представлений прокрутки, когда пользователь выполняет прокрутку.

Это означает, что я не могу просто изменить размер UIScrollView, чтобы получить то, что я хочу, без ущерба для функциональности подкачки, не так ли?

Ответ 1

Поместите scrollview в uiview и отключите clipsToBounds прокрутки. scrollview должен быть размером, который вы хотите для подкачки. вы увидите контент за пределами scrollview, но paging все равно будет тем же. Вы можете активировать clipsToBounce для внешнего вида, чтобы ограничить размер прокрутки.

Перезапишите hitTest вида, чтобы перенаправить касания на прокрутку... затем вы также сможете прокручивать, коснувшись внешнего вида прокрутки.

Ответ 2

Почему бы вам не изменить размер вашего scrollView, чтобы он соответствовал требуемой области?

Не уверен, что это поможет, но попытайтесь переопределить метод UIScrollView pointInside

- (BOOL) pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    CGRect newBounds = self.bounds;
    newBounds = CGRectInset(bounds, 0, -100.0f);
    return CGRectContainsPoint(newBounds, point);
}

Ответ 3

Пример синтаксиса 2019 года:

class LargerScrollArea: UICollectionView {

    // Example, say this is the left half of the screen, but, we wish to be
    // able to scroll on the whole width of the screen

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {

        if isUserInteractionEnabled == false { return nil }

        let extraOnRight = bounds.width
        let largerBounds = bounds.inset(by:
                UIEdgeInsets(top: 0, left: 0, bottom:0, right: -extraOnRight))
        if largerBounds.contains(point) {
            return self
        }
        else {
            return nil
        }
    }
}

(Представление коллекции, представление таблицы, все то же самое.)