Pergunta

eu tenho um NSCollectionView que contém uma coleção de CustomViews. Inicialmente, encaixou as subvisões em colunas e linhas como uma grade. Eu então defino o Columns Propriedade em IB a 1, então agora apenas os exibe um após o outro em linhas. No entanto, mesmo que meu CustomView tem 400px de largura, está definido para automaticamente, o NSCollectionView tem 400px de largura e é definido como 1 coluna, as subviews são desenhadas com cerca de 80px de largura.

Eu sei que posso contornar isso ligando:

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

Mas colocando este código no awakeFromNib método do meu WindowController Define apenas a largura correta quando o programa é lançado. Quando eu redimenso a janela (e o NSCollectionView Autorosiza como eu especifiquei), as visualizações personalizadas permanecem na largura inicialmente definida.

Fico feliz em cuidar de redimensionar as subviews, se necessário, mas sou muito novo no cacau e não consigo encontrar nenhum artigo explicando como fazer uma coisa dessas. Alguém pode me apontar na direção certa?

Anthony

Foi útil?

Solução

Blog maravilhoso de Matt Gallagher Cacau com amor é cerca de para endereçar isto. Nesta semana, ele compartilhou os detalhes das ligações de uma visão de uma coluna como a em questão:

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

Na próxima entrada, ele promete compartilhar o restante da implementação, o que deve dar o que você está procurando.

(Devo observar que ele está subclassificando diretamente a NSView e reimplementando muitos dos recursos do NSCOLLECTIONVIEW. Isso parece ser comum; poucas pessoas gostam de subclassem a NSCOLLECTIONVIEW.)

Editar: Parece que ele quebrou sua promessa ... nunca recebemos esse post. Veja a resposta de Tofutim abaixo.

Outras dicas

A verdadeira resposta é definir o maxitemSize para 0,0 (NSZeroSize). Caso contrário, é calculado.

[self.collectionView setMaxItemSize:NSZeroSize];

Isso pode ser definido em awakeFromNib.

Eu sei que isso é um muito Resposta tardia, mas tive o mesmo problema e espero que minha solução ajude alguém. A solução é acessar os limites da exibição de rolagem que não encostará a vista da coleção. Então, para resolvê -lo, você precisa substituir a primeira linha por:

CGFloat width = collectionView.enclosingScrollView.bounds.size.width;

Não consegui fazer isso funcionar com um layout padrão - mas é bastante fácil implementar um layout personalizado:

/// 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 )
    }
}

Então tudo que você precisa é

var layout=SingleColumnLayout()
collectionView.collectionViewLayout = layout

Outro tarde - eu apenas mudei para usar um NSTableView e fornecendo um NSView pelo delegate método.

Autororesing vem de graça, uma coluna é fácil e torna -se massivamente mais rápido.

Digamos que você queira sua coleçãoViewItem com um tamanho de 200x180px, então você deve definir:

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

Seu tamanho máximo deve ser grande o suficiente para parecer bom e dar espaço suficiente para alongar para se ajustar à largura da coleção.

Se você possui um número fixo de colunas, provavelmente poderá usar (0,0), mas se deseja um número dinâmico de linhas e colunas como eu queria. Você deve definir um tamanho minimizado fixo e um max.size maior.

Embora você possa ter uma visão de coleção para se comportar como você quiser, acho que você tem um problema de design

Você deve usar um NSTableView e defina colunas como 1 e seu dimensionamento para qualquer coisa, menos "nenhum". NSTableView destina -se a dados tabulares, além de reciclar células, o que oferece um ótimo aumento de desempenho para uma grande quantidade de itens. NSCollectionView é mais como um layout linear que organiza itens em uma grade, com rolagem vertical. É útil quando o número da coluna pode alterar dinamicamente para permitir que mais itens sejam mostrados na tela, geralmente dependendo da orientação do dispositivo e do tamanho da tela.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top