scrollViewWillEndDragging:withVelocity:targetContentOffset: не работает на краях UISCrollView
Я пытаюсь реализовать пользовательскую панель вкладок, которая прокручивается и имеет подкачку на каждом элементе панели вкладок. Для этого я использую делегат scrollViewWillEndDragging:withVelocity: targetContentOffset: который отлично работает с одной проблемой.
как работает моя подкачка, если contentOffset находится рядом с правильным элементом, он targetContentOffset изменяется на смещение этого элемента. То же самое с левой стороной.
проблема в том, когда я нахожусь в левой половине первый элемент и справа от последнего (вид прокрутки работает горизонтально) он должен перейти к ContentOffset 0 и смещению содержимого самого правого элемента (минус те, что на экране), но это не так.
Я проверил с отладчиком и targetContentOffset - >x действительно 0 (в первом случае - слева от самого левого элемента). Так что проблема не в UIScrollView прокрутки есть. Я заблудился.
вот мой реализованный делегат:
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
withVelocity:(CGPoint)velocity
targetContentOffset:(inout CGPoint *)targetContentOffset{
NSInteger index = lrintf(targetContentOffset->x/self.tabWidth);
targetContentOffset->x = index * self.tabWidth;
}
здесь диаграмма, объясняющая, что я хочу сделать.
|-------|-------|-------|-------|-------|-------|-------|
| | | | | | | |
| | | | | | | |
|_______|_______|_______|_______|_______|_______|_______|
|_______________________________________|
where it is and i scroll it to the left
<----|
|_______________________________________|
where it would stop
|_______________________________________|
where i want it to stop
5 ответов
кажется, это известная проблема. После некоторых исследований и разговоров с другими людьми было высказано предположение, что это может быть ошибка, которая оказалась правильной. Я сообщил об этом Apple, и он был отмечен как дубликат, но все еще открыт. Просто отвечаю за тех из вас, у кого та же проблема. Я обходил его, как предлагает Big Papoo, используя смещение, близкое к тому, что я хочу (кажется, 0.1). То же самое с правым концом.
Я попытался установить окончательное смещение на что-то немного от нуля или размер содержимого, как предложил Big Papoo, но заметил, что это удаляет отскок от прокрутки. Мое решение состояло в том, чтобы проверить исходный targetContentOffset, чтобы увидеть, равен ли он нулю или contentSize и оставить его, если это:
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
float expectedOffset = targetContentOffset->x;
if (expectedOffset == 0 || expectedOffset == scrollView.contentSize.width) return; // Scroll view will bounce so leave the targetContentOffset.
float targetOffset = [self roundedOffset:expectedOffset]; // Round your offset.
// Adjust the offset to make sure it works.
if (targetOffset == 0) targetOffset = 1;
else if (targetOffset == SCROLLVIEW_WIDTH) targetOffset = SCROLLVIEW_WIDTH - 1;
targetContentOffset->x = targetOffset;
}
вы можете, конечно, затем использовать scrollViewDidEndDecelerating:
чтобы переместить scrollview на 1 точку.
Я нашел 2 недокументированных поведения, которые вы можете исследовать : - Установка нуля, поскольку окончательное смещение не работает, я предлагаю поставить 1 или что-нибудь больше нуля (0,5 может работать, не тестируется) - Вам лучше проверить знак скорости и вычислить окончательное смещение, чтобы быть на левой или правой стороне текущей точки, где пользователь удалил палец. Не пытайтесь сделать прокрутку назад с другой стороны.
Если вы используете горизонтальное табличное представление, то внутри scrollViewWillEndDragging:withVelocity:targetContentOffset: function вы можете вызвать:
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:<index> inSection:<section>] atScrollPosition:UITableViewScrollPositionTop animated:YES];
Я обнаружил, что это работает намного лучше, чем пытаться манипулировать targetContentOffset->y в горизонтальном табличном представлении.