Question

J'ai un NSCollectionView qui contient une collection de CustomViews. Dans un premier temps, il en mosaïque les sous-vues en colonnes et des lignes comme une grille. Je puis définir la propriété Columns dans IB 1, maintenant il les affiche juste un après l'autre en rangées. Cependant, même si mon CustomView est 400px de large, il est mis à AutoResize, le NSCollectionView est 400px de large, et il est fixé à 1 colonne, les sous-vues sont tirées sur 80px large.

Je sais que je peux contourner ce problème en appelant:

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

Mais mettre ce code dans la méthode awakeFromNib de mon WindowController ne définit que la largeur correcte lorsque le programme est lancé. Quand je redimensionnez la fenêtre (et le NSCollectionView autoresizes comme je l'ai spécifié), les CustomViews restent à leur largeur initialement fixé.

Je suis heureux de prendre soin de redimensionner les sous-vues moi-même si besoin est, mais je suis tout à fait nouveau pour Cocoa et ne peut pas sembler trouver des articles expliquant comment faire une telle chose. Quelqu'un peut-il me diriger dans la bonne direction?

Anthony

Était-ce utile?

La solution

Matt Gallagher blog merveilleux Cocoa avec amour est sur les pour remédier à ce. Cette semaine, il a partagé les détails fixations d'une vue d'une colonne comme celle en question:

http://cocoawithlove.com/2010/03/designing -Voir-avec-bindings.html

entrée suivante, il promet de partager le reste de la mise en œuvre, ce qui devrait vous donner ce que vous cherchez.

(je remarque qu'il est directement et sous-classement NSView réimplémenter de nombreuses fonctions de NSCollectionView Cela semble être commun que,.. Pas beaucoup de gens sont friands de sous-classement NSCollectionView)

Modifier Semble il a rompu sa promesse ... nous n'avons reçu ce poste. Voir la réponse ci-dessous tofutim à la place.

Autres conseils

La vraie réponse consiste à définir la MaxItemSize à 0,0 (NSZeroSize). Dans le cas contraire, il est calculé.

[self.collectionView setMaxItemSize:NSZeroSize];

Cela peut être réglé dans awakeFromNib.

Je sais que c'est une réponse très en retard, mais je suis le même problème et espère que ma solution aidera quelqu'un. La solution est d'accéder à des bornes d'enfermer défilante pas de vue collection elle-même. Donc, pour le résoudre, vous devez remplacer la première ligne avec:

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

Je ne pouvais pas obtenir ce à travailler avec une mise en page par défaut - mais il est assez facile à mettre en œuvre une mise en page personnalisée:

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

tout ce que vous avez besoin est

var layout=SingleColumnLayout()
collectionView.collectionViewLayout = layout

autre fin - je viens d'utiliser un basculé NSTableView et en fournissant une NSView par la méthode delegate

.

Autoresizing est gratuit, une colonne est facile, et il rend massivement plus rapidement.

Disons que vous voulez que votre CollectionViewItem avec une taille de 200x180px, vous devez définir:

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

Votre Max-taille doit être assez grand pour bien paraître et de donner suffisamment d'espace pour étirer pour adapter la CollectionView-largeur.

Si vous avez un nombre fixe de colonnes, vous pouvez probablement utiliser (0,0), mais si vous voulez un nombre dynamique de lignes et de colonnes comme je voulais .. vous devez définir une taille minimum fixe et une plus grande max .Size.

Alors que vous pouvez obtenir une vue de collection à se comporter comme vous voulez, je pense que vous avez un problème de conception

Vous devez utiliser une NSTableView et les colonnes mises à 1 et leur dimensionnement à tout sauf « Aucun ». NSTableView est destiné aux tableaux de données, plus il peut recycler les cellules qui donne un gain de performances pour une grande quantité d'articles. NSCollectionView ressemble plus à une disposition linéaire qui organise les éléments dans une grille, avec le défilement vertical. Il est utile lorsque le numéro de colonne peut changer de façon dynamique pour permettre plus d'éléments à afficher à l'écran, généralement en fonction de l'orientation de l'appareil et la taille de l'écran.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top