Как я могу сделать uiscrollview бесконечным в iOS?

Я хочу прокрутить так: 1 2 3 1 2 3

У меня есть несколько кнопок, предположительно 10, которые я хочу показать на бесконечном свитке.

 numbercolors=[[NSMutableArray alloc] init];

 //total count of array is  49 

 numbercolors = [NSMutableArray arrayWithObjects:@"25",@"26",@"27",@"28",@"29",@"31",@"32",@"33",@"34",@"35", @"0",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12",@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22",@"23",@"24",@"25",@"26",@"27",@"28",@"29",@"30",@"31",@"32",@"33",@"34",@"35", @"0",@"1",@"2",@"3",nil];

  int x=2500;

for (NSInteger index = 0; index < [numbercolors count]; index++)
{
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];

    button.frame = CGRectMake(x ,0,29.0,77.0);

    button.tag = index;

    [button setTitle:[numbercolors objectAtIndex:index] forState:UIControlStateNormal];

    [button addTarget:self action:@selector(didTapButton:) 

    forControlEvents:UIControlEventTouchUpInside];

    [coloringScroll addSubview:button];

    x=x+70+29;
}
 [coloringScroll setContentSize:CGSizeMake(5000+ (29+70)*[numbercolors count], 1)];

 [coloringScroll setContentOffset:CGPointMake(2500+(29+70)*11, 0)];

Это мой код для make butttons на scrollview.

Как я могу установить in - (void) scrollViewDidEndDecelerating: (UIScrollView *) отправляет этот метод для бесконечного прокрутки.

Ответ 1

Просто нужно сделать set setContentOffset count

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (scrollView.contentOffset.x > 2500+(29+70)*4 + ((29+70)*36)) {
        [scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x-((29+70)*36),  0)];  
    }
    if (scrollView.contentOffset.x < 2500+(29+70)*4){
       [scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x+((29+70)*36), 0)];
    }
}

Ответ 2

Основная идея состоит в том, чтобы переместить ваш scrollview обратно в какое-то постоянное значение, когда оно было прокручено до некоторого значения, а затем автоматически переставить элементы "1", "2", "3" правильно.

Например - у вас будет scrollview с contentwidth 5000. По умолчанию вы устанавливаете его в положение 2500.

тогда вы просто проверяете - (void)scrollViewDidCScroll:(UIScrollView *)scrollview - если scrollview.contentoffset.x > 3500 - затем уменьшите его положение до scrollview.contentoffset.x - = 1000;

и то же самое о другой стороне. Это приведет к бесконечной прокрутке.

Но контент не будет следовать. Итак - вам нужно будет выполнить дополнительную проверку значения смещения содержимого для правильной настройки и правильного позиционирования "1", "2", "3", элементов.

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

Если вы не хотите повторно изобретать "колесо", проверьте эти решения:

https://www.cocoacontrols.com/controls/dmcircularscrollview

https://www.cocoacontrols.com/controls/infinitescrollview

https://www.cocoacontrols.com/controls/iainfinitegridview

Ответ 4

Я написал бесконечный подвижный подкласс UIscrollView, который выполняет эту задачу. Он основан на образце Apple StreetScroller. Вы просто предоставляете ему свои названия кнопок и хотите ли вы горизонтальный или вертикальный свиток. Вы также можете установить множество других опций. Он отправляется с документацией и примерным проектом на моем github. Вот ссылка...

http://github.com/ninefifteen/SSRollingButtonScrollView

Ответ 5

Это старый вопрос, но я пишу это, чтобы помочь тем, кто ищет такое же решение. Предположим, что мы хотим бесконечно петли через 3 элемента (ячейки) - C0, C1, C2, мы можем генерировать фиктивные ячейки в левой и правой частях центральных ячеек, результат следующим образом:

C0 C1 C2 [C0 C1 C2] C0 C1 C2

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

C0 [C1 C2C0] C1 C2C0 C1 C2

в данный момент, force contentOffset, чтобы указать правую сторону данных фиктивных ячеек,

C0 [C1 C2C0] C1 C2C0 C1 C2- > C0 C1 C2C0 [C1 C2C0] C1 C2

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

https://github.com/DragonCherry/HFSwipeView

Если вы просто хотите проверить, как это работает, нажмите ссылку ниже и "нажмите, чтобы играть".

https://www.cocoacontrols.com/controls/hfswipeview

Ответ 6

Я реализовал бесконечный скроллер в swift.
Это вдохновило яблоко StreetScroller пример

Я знаю, что еще не совершенен, но я думаю, что это божественная точка начала.

InfiniteVerticalScroller

Ответ 7

Для правильной бесконечной прокрутки вы можете использовать -

        let rightOffset = CGPoint.init(x: (scrollView.contentSize.width) - (scrollView.bounds.width), y: 0)
    UIView.animate(withDuration: 3.0,
                   delay: 0.0,
                   options: [.curveLinear, .repeat],
                   animations: { () -> Void in
                    self.scrollView.contentOffset = rightOffset

    }, completion: { (finished: Bool) -> Void in
        self.scrollView.setContentOffset(.init(x: 0, y: self.scrollView.contentOffset.y), animated: false)
    })

Ответ 8

Ответы, приведенные здесь, хороши, но если вы все еще не удовлетворены и ищете другой подход, то, что я сделал.

Основная идея состоит в том, чтобы обновлять количество ячеек каждый раз, когда вы достигаете ячейки до последней. Каждый раз, когда вы увеличиваете количество предметов на 1, это создает иллюзию бесконечной прокрутки. Для этого мы можем использовать scrollViewDidEndDecelerating(_ scrollView: UIScrollView) чтобы определить, когда пользователь завершил прокрутку, а затем обновить количество элементов в представлении коллекции. Вот фрагмент кода для достижения этой цели:

class InfiniteCarouselView: UICollectionView {

    var data: [Any] = []

    private var currentIndex: Int?
    private var currentMaxItemsCount: Int = 0
    // Set up data source and delegate
}

extension InfiniteCarouselView: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        // Set the current maximum to a number above the maximum count by 1
        currentMaxItemsCount = max(((currentIndex ?? 0) + 1), data.count) + 1
        return currentMaxItemsCount

    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
        let row = indexPath.row % data.count
        let item = data[row]
        // Setup cell
        return cell
    }
}

extension InfiniteCarouselView: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: collectionView.frame.width, height: collectionView.frame.height)
    }

    // Detect when the collection view has finished scrolling to increase the number of items in the collection view
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        // Get the current index. Note that the current index calculation will keep changing because the collection view is expanding its content size based on the number of items (currentMaxItemsCount)
        currentIndex = Int(scrollView.contentOffset.x/scrollView.contentSize.width * CGFloat(currentMaxItemsCount))
        // Reload the collection view to get the new number of items
        reloadData()
    }
}

Pros

  • Простая реализация
  • Не использовать Int.max (что, по моему мнению, не очень хорошая идея)
  • Не использовать произвольное число (например, 50 или что-то еще)
  • Без изменений или манипуляций с данными
  • Нет ручного обновления смещения содержимого или любых других атрибутов прокрутки

Cons

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