Подтвердить что ты не робот

UICollectionView - Горизонтальная прокрутка, горизонтальная компоновка?

У меня есть UIScrollView, который выдает сетку значков. Если бы вы представили макет для iOS Springboard, вы бы приблизились к правилу. Он имеет горизонтальный прокручиваемый свиток (точно так же, как и Springboard). Однако, похоже, что макет не совсем прав. Похоже, что он кладет предметы сверху вниз. В результате мой последний столбец содержит только две строки из-за количества отображаемых элементов. Я бы предпочел, чтобы моя последняя строка на последней странице имела 2 элемента, например, вы видели бы в Springboard.

Как это можно сделать с помощью UICollectionView и связанных с ним классов? Должен ли я писать пользовательский UICollectionViewFlowLayout?

4b9b3361

Ответ 1

1-й подход

Как насчет использования UIPageViewController с массивом UICollectionViewControllers? Вам нужно будет забрать правильное количество элементов в каждом UICollectionViewController, но это не должно быть сложно. Вы получите точно такой же вид, как у Springboard.

Второй подход

Я подумал об этом и, на мой взгляд, вам нужно установить:

self.collectionView.pagingEnabled = YES;

и создайте собственный макет вида коллекций путем подкласса UICollectionViewLayout. Из пользовательского объекта макета вы можете получить доступ к self.collectionView, чтобы узнать, каков размер представления коллекции frame, numberOfSections и numberOfItemsInSection:. С помощью этой информации вы можете вычислить ячейки framesprepareLayout) и collectionViewContentSize. Вот несколько статей о создании пользовательских макетов:

Третий подход

Вы можете сделать это (или приблизиться к нему) без создания пользовательского макета. Добавьте UIScrollView в пустой вид, включите в него пейджинг. В представлении прокрутки добавьте представление коллекции. Затем добавьте к нему ограничение ширины, проверьте код, сколько у вас элементов, и установите его constant на правильное значение, например. (self.view.frame.size.width * numOfScreens). Вот как это выглядит (цифры на ячейках показывают indexPath.row): https://www.dropbox.com/s/ss4jdbvr511azxz/collection_view.mov Если вас не устраивает способ упорядочивания ячеек, то я боюсь, вам придется пойти с 1. или 2.

Ответ 2

Вы пытались настроить направление прокрутки вашего UICollectionViewFlowLayout на горизонтальное?

[yourFlowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];

И если вы хотите, чтобы страница была такой же, как в плагине, вам нужно включить пейджинг в виде коллекции так:

[yourCollectionView setPagingEnabled:YES];

Ответ 3

Вам нужно уменьшить высоту UICollectionView до высоты своей ячейки/позиции и выбрать "Horizontal" из "Scroll Direction", как показано на скриншоте ниже. Затем он будет прокручиваться горизонтально в зависимости от numberOfItems, который вы вернули в своей реализации источника данных.

enter image description here

Ответ 4

Просто для удовольствия, другой подход состоял бы в том, чтобы просто оставить набор подкачки и горизонтальную прокрутку, добавить метод, который изменяет порядок элементов массива для преобразования от "сверху вниз", "слева направо" на визуально 'слева направо, сверху вниз' и заполните промежуточные ячейки пустыми скрытыми ячейками, чтобы сделать интервал правильным. В случае 7 пунктов в сетке из 9 это будет выглядеть следующим образом:

[1][4][7]
[2][5][ ]
[3][6][ ]

должен стать

[1][2][3]
[4][5][6]
[7][ ][ ]

так что 1 = 1, 2 = 4, 3 = 7 и т.д., а 6 = пусто. Вы можете переупорядочить их, вычислив общее количество строк и столбцов, затем вычислить номер строки и столбца для каждой ячейки, изменить строку для столбца и наоборот, а затем у вас есть новые индексы. Когда ячейка не имеет значения, соответствующего изображению, вы можете вернуть пустую ячейку и установить для нее cell.hidden = YES;.

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

Обновление

Я сомневаюсь, что это лучшее решение, но по запросу здесь работает код:

- (void)viewDidLoad {
    // Fill an `NSArray` with items in normal order
    items = [NSMutableArray arrayWithObjects:
             [NSDictionary dictionaryWithObjectsAndKeys:@"Some label 1", @"label", @"Some value 1", @"value", nil],
             [NSDictionary dictionaryWithObjectsAndKeys:@"Some label 2", @"label", @"Some value 2", @"value", nil],
             [NSDictionary dictionaryWithObjectsAndKeys:@"Some label 3", @"label", @"Some value 3", @"value", nil],
             [NSDictionary dictionaryWithObjectsAndKeys:@"Some label 4", @"label", @"Some value 4", @"value", nil],
             [NSDictionary dictionaryWithObjectsAndKeys:@"Some label 5", @"label", @"Some value 5", @"value", nil],
              nil
              ];

    // Calculate number of rows and columns based on width and height of the `UICollectionView` and individual cells (you might have to add margins to the equation based on your setup!)
    CGFloat w = myCollectionView.frame.size.width;
    CGFloat h = myCollectionView.frame.size.height;
    rows = floor(h / cellHeight);
    columns = floor(w / cellWidth);
}

// Calculate number of sections
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return ceil((float)items.count / (float)(rows * columns));
}

// Every section has to have every cell filled, as we need to add empty cells as well to correct the spacing
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return rows*columns;
}

// And now the most important one
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell *cell = [collectionView [email protected]"myIdentifier" forIndexPath:indexPath];

    // Convert rows and columns
    int row = indexPath.row % rows;
    int col = floor(indexPath.row / rows);
    // Calculate the new index in the `NSArray`
    int newIndex = ((int)indexPath.section * rows * columns) + col + row * columns;

    // If the newIndex is within the range of the items array we show the cell, if not we hide it
    if(newIndex < items.count) {
        NSDictionary *item = [items objectAtIndex:newIndex];
        cell.label.text = [item objectForKey:@"label"];
        cell.hidden = NO;
    } else {
        cell.hidden = YES;
    }

    return cell;
}

Если вы хотите использовать метод didSelectItemAtIndexPath, вы должны использовать то же преобразование, которое используется в cellForItemAtIndexPath, чтобы получить соответствующий элемент. Если у вас есть поля ячейки, вам нужно добавить их в расчёт строк и столбцов, так как они должны быть правильными, чтобы это работало.

Ответ 5

Я работаю над Xcode 6.2 и для горизонтальной прокрутки. Я изменил направление прокрутки в инспекторе атрибутов.

нажмите на collectionView- > attribute inspector- > scroll Direction- > изменить на горизонтальный

enter image description here Надеюсь, это поможет кому-то.

Ответ 6

Если вы определяете UICollectionViewFlowLayout в коде, он будет переопределять конфигурации интерфейса Builder. Следовательно, вам нужно снова определить scrollDirection.

let layout = UICollectionViewFlowLayout()
...
layout.scrollDirection = .Horizontal
self.awesomeCollectionView.collectionViewLayout = layout

Ответ 7

Из @Erik Hunter, я отправляю полный код для создания горизонтального UICollectionView

UICollectionViewFlowLayout *collectionViewFlowLayout = [[UICollectionViewFlowLayout alloc] init];
[collectionViewFlowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
self.myCollectionView.collectionViewLayout = collectionViewFlowLayout;

В Swift

let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .Horizontal
self.myCollectionView.collectionViewLayout = layout

В Swift 3.0

let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .Horizontal
self.myCollectionView.collectionViewLayout = layout

Надеемся на эту помощь

Ответ 8

Мы можем выполнять одно и то же поведение Springboard с использованием UICollectionView, и для этого нам нужно написать код для пользовательского макета.

Я достиг этого с помощью моей специальной реализации класса макета с "SMCollectionViewFillLayout"

Репозиторий кода:

https://github.com/smindia1988/SMCollectionViewFillLayout

Вывод, как показано ниже:

1.png

First.png

2_Code_H-Scroll_V-Fill.png

введите описание изображения здесь

3_Output_H-Scroll_V-Fill.png введите описание изображения здесь

4_Code_H-Scroll_H-Fill.png введите описание изображения здесь

5_Output_H-Scroll_H-Fill.png введите описание изображения здесь

Ответ 9

Этот код хорошо работает в Swift 3.1 и Xcode 8.3.2

override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        self.collectionView.collectionViewLayout = layout
        self.collectionView!.contentInset = UIEdgeInsets(top: -10, left: 0, bottom:0, right: 0)

        if let layout = self.collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
            layout.minimumInteritemSpacing = 0
            layout.minimumLineSpacing = 0
            layout.itemSize = CGSize(width: self.view.frame.size.width-40, height: self.collectionView.frame.size.height-10)
            layout.invalidateLayout()
        }

    }

Ответ 10

для xcode 8 я сделал это, и он работал:

Ответ 11

Вы можете написать собственный макет UICollectionView, чтобы достичь этого, вот демонстрационный образ моей реализации:

demo image

Здесь репозиторий кода: KSTCollectionViewPageHorizontalLayout

@iPhoneDev (возможно, это тоже поможет)