Расширение UIScrollView и мониторинг событий прокрутки - PullRequest
14 голосов
/ 05 апреля 2009

Я хочу реализовать пользовательское, многократно используемое и эффективное поведение прокрутки в приложении для iPhone, поэтому я расширяю UIScrollView с помощью своего пользовательского элемента управления и хочу отслеживать движения прокрутки.

Теперь я знаю, что, возможно, я могу назначить свой пользовательский элемент управления как UIScrollViewDelegate и внутренне отвечать на вызовы scrollViewDidScroll , но мне это не кажется правильным (я могу неправильно).

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

Как прямой потомок UIScrollView Я ожидаю, что смогу переопределить метод, который запускает вызов делегата scrollViewDidScroll , или получить доступ к шаблонному методу, или прослушать для событий прокрутки, но я не вижу таких вариантов.

Глядя на файл UITableView.h , UITableView не выглядит как UISCrollViewDelegate , поэтому мне интересно, как это удается ( Я предполагаю, что, поскольку он перерабатывает ячейки, он должен отслеживать их положение относительно видимых границ).

Я довольно новичок в этой платформе, поэтому я могу упустить что-то очевидное. Любая помощь приветствуется.

Ответы [ 6 ]

18 голосов
/ 19 апреля 2011

Нашел это !! (совершенно случайно)

Я смирился с тем, чтобы назначить свой подкласс UIScrollView в качестве делегата супер, а затем реализовать метод делегата scrollViewDidScroll: , однако в процессе реализации я получил исключение в середине моего метода scrollViewDidScroll. Беглый взгляд на трассировку стека показал, что мой метод делегата действительно вызывался из setContentOffset:

Оказывается, если вы переопределите setContentOffset: , вы получите вызов при каждом перемещении представления прокрутки! и он поставляется с удобной структурой contentOffset, которая сообщает вам, где находится представление прокрутки:)

- (void)setContentOffset:(CGPoint)contentOffset
{
    [super setContentOffset:contentOffset];

    NSLog(@"ViewDidScroll: %f, %f", contentOffset.x, contentOffset.y);
}
3 голосов
/ 26 мая 2009

Я согласен с вашей первоначальной оценкой. Если вы изменяете саму логику прокрутки (а не реагируете на прокрутку), то это подкласс, а не делегат.

UIScrollView предназначен для создания подклассов и включает в себя небольшую дискуссию об этом в справочнике. В частности, он предлагает переопределить -touchesShouldBegin:withEvent:inContent:, pagingEnabled и touchesShouldCancelInContentView:, которые, вероятно, являются тем местом, где вы хотите выполнять работу, которую вы описываете.

2 голосов
/ 08 января 2016

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

Джо-эль-ответ правильный для Obj-C. Вот оно в Свифте:

class FeedScrollView: UIScrollView {

    override var contentOffset: CGPoint {
        willSet(newContentOffset) {
            print("About to set Offset: \(newContentOffset)")
        }
    }
}
0 голосов
/ 05 декабря 2013

Вы можете использовать следующий протокол для прослушивания позиции прокрутки:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    NSLog(@"scroll");
}

См. эту ссылку (документы Apple на UIScrollViewDelegate).

См. эту ссылку также (некоторый код для настройки делегата).

0 голосов
/ 06 апреля 2009

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

Вы также можете предоставить свой собственный пользовательский объект / протокол делегата тому, что UIViewController использует ваше представление прокрутки для выполнения некоторой логики, специфичной для представления.

0 голосов
/ 06 апреля 2009

(я могу ошибаться)

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

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