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

Как настроить размер ячейки UICollectionView для каждого класса размера?

Я нахожу трение при попытке создать отзывчивую/адаптивную UICollectionViewCells в UIStoryboard.

Проблема, которую я вижу, заключается в том, что вы, похоже, не можете установить Cell Size per Size Class, и я пытаюсь установить правильный подход к этому. Я разработал ячейки, чтобы приспособиться к их контейнерам, чтобы они автоматически зависали независимо от класса размера. В основном это работает в том случае, если я изменяю класс размера, выбираю вид моей ячейки и делаю Update Frames, тогда все они изменяются в соответствии с их новым размером. Однако это одноразовая сделка, если я вернусь в класс Any/Any size, то я все еще вижу эту измененную версию.

Вот что я знаю, я мог бы попробовать:

  • Создайте несколько ячеек с фиксированными размерами, по одному на класс размера и в представлении раскадровки. Тогда я мог бы использовать только один из них во время выполнения, но я мог бы увидеть их во время разработки.
  • Я мог бы создать класс коллекции Per Size, каждый из которых будет установлен только для этого размера. Это будет работать, но будет больно управлять несколькими UICollectionViews
  • Создайте мой интерфейс и/или ограничения программно (теряя видимость дизайна).

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

4b9b3361

Ответ 1

Решение, с которым я столкнулся, состояло в том, чтобы реализовать UICollectionViewDelegateFlowLayout и реализовать метод sizeForItemAtIndexPath. Это означает, что размеры ячеек можно установить в соответствии с имеющимися размерами Size Class.

Это все еще не идеально, поскольку вы не можете видеть изменения в раскадровке, и вы не можете создать универсальный дизайн и видеть его в каждом из разных форматов.

Я все еще надеюсь, что у кого-то есть лучший вариант.

Ответ 2

Здесь аналогичное решение закодировано в Swift. Я просто создал оба моих ячеек в раскадровке и оставил их видимыми для любой комбинации классов размеров. Когда изменения коллекции признаков я обновляю cellSize и cellReuseID, которые я хочу использовать, и сообщаем, что collectionView перезагружает все видимые ячейки. Тогда

collectionView(collectionView: UICollectionView,
    layout collectionViewLayout: UICollectionViewLayout,
    sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize

и

override func collectionView(collectionView: UICollectionView,
    cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell

(не показаны в примере кода), который позволяет мне обновлять размер ячейки и обновлять стиль раскадровки ячейки. Так что не полностью сделано в раскадровке, но достаточно хорошо, пока в Xcode не будет предоставлена ​​дополнительная поддержка.

struct MyCollectionViewConstants{
    static let CELL_ANY_ANY_REUSE_ID = "cell";
    static let CELL_COMPACT_REGULAR_REUSE_ID = "cellSmall"
    static let CELL_ANY_ANY_SIZE = 100;
    static let CELL_COMPACT_REGULAR_SIZE = 70;
}

class MyCollectionView: UICollectionViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

    var cellSize = MyCollectionViewConstants.CELL_ANY_ANY_SIZE
    var cellReuseID = MyCollectionViewConstants.CELL_ANY_ANY_REUSE_ID


    func collectionView(collectionView: UICollectionView,
        layout collectionViewLayout: UICollectionViewLayout,
        sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize{

        return CGSize(width: cellSize, height: cellSize)
    }

    override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)

        if (self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClass.Compact
            && self.traitCollection.verticalSizeClass == UIUserInterfaceSizeClass.Regular){
            cellSize = MyCollectionViewConstants.CELL_COMPACT_REGULAR_SIZE
            cellReuseID = MyCollectionViewConstants.CELL_COMPACT_REGULAR_REUSE_ID
        } else {
            cellSize = MyCollectionViewConstants.CELL_ANY_ANY_SIZE
            cellReuseID = MyCollectionViewConstants.CELL_ANY_ANY_REUSE_ID
        }

        self.collectionView.reloadItemsAtIndexPaths(
            self.collectionView.indexPathsForVisibleItems())
    }
}

Ответ 3

У меня возникла такая же проблема после внедрения класса размера (iPad и iPhone). Хорошо, я понял решение. Надеюсь, это поможет!

Внедрение UICollectionViewDelegateFlowLayout.

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
    {
         var device = UIDevice.currentDevice().model  
         var cellSize:CGSize = CGSizeMake(155, 109)

         if (device == "iPad" || device == "iPad Simulator") {
            cellSize = CGSizeMake(240, 220) 
         }

         return cellSize
    }