Изменить направление прокрутки в UICollectionView

У меня есть UICollectionView, который я настроил, все работает нормально (выбор, заголовки и т. д.), однако в некоторых ситуациях я хочу изменить направление прокрутки.

Короче говоря, если я захожу в раскадровку и меняю scrollDirection, он работает нормально, но я хочу сделать это программно!

Я попытался изменить направление прокрутки представления коллекции напрямую с помощью чего-то вроде

    [myCollectionView setScrollDirection:....and so on.......

Но это не работает, я не могу найти scrollDirection или что-то подобное там.

Я также пытался настроить макет потока, но я уверен, что делаю это неправильно (т.е. пытаюсь установить ViewLayout в FlowLayout).

    UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc]init];
    [flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
    [myCollectionView setCollectionViewLayout:flowLayout];

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

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

Короче говоря, есть ли простой способ сделать это или нет? ИЛИ кто-нибудь знает хороший учебник по Flow Layout?

РЕДАКТИРОВАТЬ

Я настраиваю представление коллекции как таковое;

[myCollectionView setDataSource:self];
[myCollectionView setDelegate:self];

Я реализую эти методы делегирования, и все работает нормально

viewForSupplementaryElementOfKind
numberOfSectionsInCollectionView
numberOfItemsInSection
cellForItemAtIndexPath
didSelectItemAtIndexPath

Я добавил DataSource и Delegate в .h, а также делегат FlowLayout, НО я не уверен, что мне также нужно для последнего.

Большая часть визуального макета выполняется в Story Board, есть несколько вещей, таких как шрифт, размер и цвет, которые я делаю программно.

ДРУГОЕ РЕДАКТИРОВАНИЕ

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

Невозможно одновременно удовлетворить ограничения. Вероятно, по крайней мере одно из ограничений в следующем списке вам не нужно. Попробуйте следующее: (1) посмотрите на каждое ограничение и попытайтесь выяснить, чего вы не ожидаете; (2) найти код, который добавил нежелательное ограничение или ограничения, и исправить его. (Примечание. Если вы видите NSAutoresizingMaskLayoutConstraints, которые не понимаете, обратитесь к документации по свойству UIView translatesAutoresizingMaskIntoConstraints.)

"<NSAutoresizingMaskLayoutConstraint:0x89967f0 h=--& v=--& V:[menuCell:0x8991700(50)]>",
"<NSLayoutConstraint:0x8991200 menuCell:0x8991700.bottom == UILabel:0x8992be0.bottom + 100>",
"<NSLayoutConstraint:0x898fd50 UILabel:0x8992be0.top == menuCell:0x8991700.top + 3>"

Попытается восстановиться, нарушив ограничение

Прервите objc_exception_throw, чтобы перехватить это в отладчике. Также могут быть полезны методы из категории UIConstraintBasedLayoutDebugging в UIView, перечисленные в .


person Recycled Steel    schedule 13.01.2014    source источник
comment
Соответствует ли представление, в котором отображается представление коллекции, протоколу UICollectionViewFlowLayoutDelegate? Вы уверены, что объем контента, который вы пытаетесь нарисовать, достаточно велик, чтобы обеспечить фактическую прокрутку представления коллекции? Можем ли мы увидеть больше настроек представления коллекции? Вы двигаетесь в правильном направлении, пытаясь установить направление прокрутки в Flow Layout, так что хорошее начало!   -  person Matthew Hallatt    schedule 13.01.2014
comment
@MatthewHallatt Я добавил немного больше информации. Это большой стол, в нем может быть 50-60 предметов в 4-5 секциях. Представление коллекции представляет собой длинную полосу внизу, которая прокручивается горизонтально, можно нажать кнопку, которая заставит коллекцию расшириться почти до большей части экрана (который работает), но я хочу, чтобы прокрутка перешла к вертикальной прокрутке.   -  person Recycled Steel    schedule 13.01.2014


Ответы (4)


Хорошо, попробуйте вызвать invalidateLayout в представлении коллекции следующим образом:

[myCollectionView.collectionViewLayout invalidateLayout];

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

Посмотрим, получится ли у вас что-то близкое!

person Matthew Hallatt    schedule 13.01.2014
comment
Я попробовал это, но получил тот же результат, для ясности я также указал всю ошибку в своем вопросе. Я быстро дохожу до того, что просто добавлю два представления коллекции и покажу/скрою их при необходимости, но это кажется пустой тратой ресурсов. - person Recycled Steel; 14.01.2014
comment
Вы устанавливаете свои собственные ограничения в своей камере? Если да, то программно или в конструкторе интерфейсов? Проблема, похоже, в том, что вы, возможно, пытаетесь сохранить высоту метки одинаковой, но держите ее на определенном расстоянии как от верхней, так и от нижней части ячейки. Если вы устанавливаете свои собственные ограничения, попробуйте удалить тот, который удерживает метку в нижней части ячейки, или, может быть, тот, который ограничивает высоту метки. Или, может быть, я лаял не на то дерево со всем этим комментарием! - person Matthew Hallatt; 14.01.2014
comment
Похоже, все это делается в конструкторе интерфейсов. Там нет никаких ограничений, поэтому я предполагаю, что они выполняются автоматически. Я пытался добавить некоторые, но то же самое. - person Recycled Steel; 14.01.2014
comment
Делаете ли вы что-нибудь в методе «prepareForReuse» для своих ячеек? Если нет, попробуйте установить для текста метки значение nil (@) и для любых изображений также значение nil, на всякий случай! - person Matthew Hallatt; 14.01.2014
comment
Я попытался вернуть nil для представления в viewForSupplementaryElementOfKind, которое рисует верхние и нижние колонтитулы, но это сделало то же самое. Я делаю копию и удаляю весь верхний колонтитул, потому что (как вы говорите) он выглядит как-то там. - person Recycled Steel; 14.01.2014
comment
и не использовать prepareForReuse. - person Recycled Steel; 14.01.2014
comment
Используете ли вы собственный подкласс UICollectionViewCell или просто по умолчанию? Вы говорите, что ячейка настроена в конструкторе интерфейса: вы должны иметь возможность отключить автомакет на первой вкладке панели «Утилиты» с правой стороны (см. goodbyehelicopter.com/2012/02 / например). Посмотрите, поможет ли это. Вызванные ошибки определенно связаны с автомакетом, поэтому его отключение должно исправить эти ошибки, но ваши ячейки могут выглядеть неправильно. - person Matthew Hallatt; 14.01.2014
comment
Попробую без Autolayout. Я быстро прихожу к выводу, что Autolayout бесполезен, ваше приложение меняет ориентацию и содержит множество сложных компонентов. - person Recycled Steel; 14.01.2014
comment
@MatthewHallett Я удалил Autolayout, который остановил сбой, однако collectionView не меняет направление прокрутки. Я меняю flowLayout, как и раньше, и делаю макет недействительным, есть ли что-нибудь еще? - person Recycled Steel; 14.01.2014
comment
Заработало (небольшая ошибка), это также исправлено с помощью Autolayout. - person Recycled Steel; 14.01.2014
comment
давайте продолжим это обсуждение в чате - person Matthew Hallatt; 14.01.2014

сделай это:

- (IBAction)changeDirection:(UIButton *)sender
{
     UICollectionViewFlowLayout *layout = (UICollectionViewFlowLayout *)[self.collectionView collectionViewLayout];
     if(layout.scrollDirection == UICollectionViewScrollDirectionHorizontal)
     {
        layout.scrollDirection = UICollectionViewScrollDirectionVertical;
     }
     else
     {
         layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
     }
}

Меня устраивает.

person Pratham Mehta    schedule 28.03.2014
comment
Все еще не работает для меня. Даже если я вызову [layout invalidateLayout] после этого изменения - person Arsynth; 18.06.2014
comment
Рад помочь :) - person Pratham Mehta; 02.07.2015

В Swift вы можете сделать это:

//From the collection view subclass
    if let layout: UICollectionViewFlowLayout = self.collectionViewLayout as? UICollectionViewFlowLayout {
        layout.scrollDirection = .Vertical
    }
person prolfe    schedule 06.11.2015

Вы можете сделать это с помощью обозревателя свойств didSet{} с выходом представления коллекции.

Предполагая, что выходом для collectionView является myCollectionView, в коде добавьте наблюдатель свойства didSet к выходу и измените направление макета. Что-то типа-

@IBOutlet weak var myCollectionView:UICollectionView!{
      didSet{
            let layout = contentCollectionView.collectionViewLayout as!
UICollectionViewFlowLayout
            layout.scrollDirection = .Vertical
        }
}

Обычно collectionView удаляется в раскадровке из библиотеки объектов, он автоматически поставляется с FlowLayout. Вы можете изменить направление потока этого макета, сообщив своему коду, что, когда я получаю представление своей коллекции, я хочу, чтобы направление прокрутки его макета было горизонтальным или вертикальным.

person Natasha    schedule 03.06.2019