Может ли NSCollectionView автоматически изменять ширину своих подпредставлений для отображения одного столбца - PullRequest
9 голосов
/ 21 января 2010

У меня есть NSCollectionView, который содержит коллекцию CustomViews. Первоначально он разбил подпредставления на столбцы и строки, как сетка. Затем я установил для свойства Columns в IB значение 1, и теперь он просто отображает их один за другим в строках. Однако, хотя мой CustomView имеет ширину 400px, для него установлено автоматическое изменение размера, NSCollectionView имеет ширину 400px и установлен в 1 столбец, подпредставления отображаются шириной около 80px.

Я знаю, что могу обойти это, позвонив:

CGFloat width = collectionView.bounds.size.width;
NSSize size = NSMakeSize(width, 85);
[collectionView setMinItemSize:size];
[collectionView setMaxItemSize:size];

Но помещение этого кода в метод awakeFromNib моего WindowController только устанавливает правильную ширину при запуске программы. Когда я изменяю размер окна (и NSCollectionView автоматически изменяет размеры, как я указал), CustomViews остаются на своей изначально установленной ширине.

Я с удовольствием позабочусь о том, чтобы самостоятельно изменить размеры подпредставлений, но я довольно новичок в Какао и, похоже, не могу найти никаких статей, объясняющих, как это сделать. Может ли кто-нибудь указать мне правильное направление?

Anthony

Ответы [ 7 ]

9 голосов
/ 27 февраля 2014

Правильный ответ - установить для maxItemSize значение 0,0 (NSZeroSize). В противном случае оно вычисляется.

[self.collectionView setMaxItemSize:NSZeroSize];

Это может быть установлено в awakeFromNib.

3 голосов
/ 08 мая 2013

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

CGFloat width = collectionView.enclosingScrollView.bounds.size.width;
2 голосов
/ 23 января 2017

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

/// Simple single column layout, assuming only one section
class SingleColumnLayout: NSCollectionViewLayout {

    /// Height of each view in the collection
    var height:CGFloat = 100

    /// Padding is wrapped round each item, with double an extra bottom padding above the top item, and an extra top padding beneath the bottom
    var padding = EdgeInsets.init(top: 5, left: 10, bottom: 5, right: 10)

    var itemCount:Int {
        guard let collectionView = collectionView else {
            return 0
        }

        return collectionView.numberOfItems(inSection:0)
    }

    override func shouldInvalidateLayout(forBoundsChange newBounds: NSRect) -> Bool {
        return true
    }

    override open func layoutAttributesForItem(at indexPath: IndexPath) -> NSCollectionViewLayoutAttributes? {
        let attributes = NSCollectionViewLayoutAttributes(forItemWith: indexPath)
        guard let collectionView = collectionView else {
            return attributes
        }

        let bounds = collectionView.bounds
        let itemHeightWithPadding = height + padding.top + padding.bottom
        let row = indexPath.item

        attributes.frame = NSRect(x: padding.left, y: itemHeightWithPadding * CGFloat(row) + padding.top + padding.bottom , width: bounds.width - padding.left - padding.right , height: height)
        attributes.zIndex = row

        return attributes
    }

    //If you have lots of items, then you should probably do a 'proper' implementation here
    override open func layoutAttributesForElements(in rect: NSRect) -> [NSCollectionViewLayoutAttributes] {
        var attributes = [NSCollectionViewLayoutAttributes]()

        if (itemCount>0){
            for index in 0...(itemCount-1) {
                if let attribute = layoutAttributesForItem(at: NSIndexPath(forItem: index, inSection: 0) as IndexPath) {
                    attributes.append(attribute)
                }
            }
        }

        return attributes
    }

    override open var collectionViewContentSize: NSSize {

        guard let collectionView = collectionView else {
            return NSSize.zero
        }

        let itemHeightWithPadding = height + padding.top + padding.bottom

        return NSSize.init(width: collectionView.bounds.width, height: CGFloat(itemCount) * itemHeightWithPadding + padding.top + padding.bottom )
    }
}

тогда все что вам нужно это

var layout=SingleColumnLayout()
collectionView.collectionViewLayout = layout
1 голос
/ 20 октября 2014

еще один поздний - я просто переключился на использование NSTableView и предоставление NSView методом delegate.

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

0 голосов
/ 27 февраля 2015

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

Вы должны использовать NSTableView и установить для столбцов значение 1, а их размеры будут отличаться от «Нет»,NSTableView предназначен для табличных данных, плюс он может перерабатывать ячейки, что дает большой прирост производительности для большого количества элементов.NSCollectionView больше похоже на линейный макет, который упорядочивает элементы в сетке с вертикальной прокруткой.Это полезно, когда номер столбца может динамически изменяться, чтобы на экране можно было отображать больше элементов, обычно в зависимости от ориентации устройства и размера экрана.

0 голосов
/ 13 декабря 2014

Допустим, вы хотите, чтобы ваш CollectionViewItem имел размер 200x180px, тогда вы должны установить:

[myCollectionView setMinItemSize:NSMakeSize(200, 180)];
[myCollectionView setMaxItemSize:NSMakeSize(280, 250)];

Ваш максимальный размер должен быть достаточно большим, чтобы хорошо выглядеть, и иметь достаточно места для растяжения, чтобы соответствовать collectionView-Width.

Если у вас фиксированное количество столбцов, вы, вероятно, можете использовать (0,0), но если вы хотите динамическое количество строк и столбцов, как я хотел ... вам следует установить фиксированный минимальный размер и больший максимальный .size.

0 голосов
/ 11 марта 2010

Замечательный блог Мэтта Галлахера Какао с любовью - это примерно для решения этой проблемы. На этой неделе он поделился подробностями связывания представления в одну колонку, подобного рассматриваемому:

http://cocoawithlove.com/2010/03/designing-view-with-bindings.html

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

(Я должен отметить, что он непосредственно создает подклассы NSView и повторно реализует многие из функций NSCollectionView. Однако это кажется распространенным явлением; не многие люди любят подклассифицировать NSCollectionView.)

Редактировать: Кажется, он нарушил свое обещание ... мы так и не получили этот пост. Вместо этого см. Ответ тофутима ниже.

...