Can NSCollectionView AUTORESIZE die Breite seines Subviews eine Spalte angezeigt werden
-
22-09-2019 - |
Frage
ich eine NSCollectionView
haben, die eine Sammlung von CustomViews
enthält. Zunächst gefliest es die Subviews in Spalten und Zeilen wie ein Raster. Ich habe dann die Columns
Eigenschaft in IB zu 1, so jetzt ist es nur zeigt sie eine nach der anderen in den Reihen. Doch obwohl meine CustomView
ist 400px breit, es ist Satz Autoresize, die NSCollectionView
ist 400px breit, und es ist auf 1 gesetzt Spalte werden die Subviews über 80px breit gezogen.
Ich weiß, dass ich dies telefonisch umgehen kann:
CGFloat width = collectionView.bounds.size.width;
NSSize size = NSMakeSize(width, 85);
[collectionView setMinItemSize:size];
[collectionView setMaxItemSize:size];
Aber setzt diesen Code in der awakeFromNib
Methode meiner WindowController
setzt nur die richtige Breite, wenn das Programm startet. Wenn ich die Größe des Fensters (und die NSCollectionView
autoresizes wie ich angegeben haben), die Custom Aufenthalt in ihrem anfänglich eingestellten Breite.
Ich bin glücklich, zu kümmern, die Subviews selbst Ändern der Größe, wenn es sein muss, aber ich bin ganz neu in Cocoa und kann nicht scheinen, keine Artikel zu finden, zu erklären, wie so etwas zu tun. Kann jemand Punkt mich in die richtige Richtung?
Anthony
Lösung
Matt Gallagher wunderbarer Blog Cocoa with Love ist über um das zu erwähnen. In dieser Woche teilte er die Bindungen Details einer Ein-Spalten-Ansicht wie die in Frage:
http://cocoawithlove.com/2010/03/designing -Blick-with-bindings.html
Nächster Eintrag, verspricht er den Rest der Implementierung zu teilen, die Sie sollten das, was Sie suchen.
(sollte ich beachten Sie, dass er NSView ist Subklassen direkt und Neuimplementierung Funktionen viele NSCollectionView des Dies scheint üblich zu sein, obwohl;.. Nicht viele Leute sind gern Subklassen NSCollectionView)
Edit: Es scheint er sein Versprechen brach ... wir haben nie die Post. Siehe tofutim Antwort unten statt.
Andere Tipps
Die wahre Antwort ist die MaxItemSize auf 0,0 (NSZeroSize
) einzustellen. Andernfalls wird es berechnet wird.
[self.collectionView setMaxItemSize:NSZeroSize];
Dies kann in awakeFromNib
eingestellt werden.
Ich weiß, das ist eine sehr späte Antwort, aber ich habe das gleiche Problem und hoffe, dass meine Lösung jemanden helfen. Die Lösung ist, den Zugang Grenzen selbst scroll Blick nicht von Sammlungsansicht umschließt. Also, es zu lösen Sie erste Zeile mit ersetzen müssen:
CGFloat width = collectionView.enclosingScrollView.bounds.size.width;
Ich konnte nicht mit einem Standard-Layout an der Arbeit diese - aber es ist ziemlich einfach, ein eigenes Layout zu implementieren:
/// 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 )
}
}
dann alles, was Sie brauchen, ist
var layout=SingleColumnLayout()
collectionView.collectionViewLayout = layout
ein weiterer spät - ich wechselte gerade einen NSTableView
zu verwenden und eine NSView
durch die delegate
Methode bietet
automatische Größen kostenlos kommt, eine Spalte ist einfach, und es macht massiv schneller.
Lassen Sie uns sagen Sie Ihren CollectionViewItem mit einer Größe von 200x180px, dann sollten Sie ein:
[myCollectionView setMinItemSize:NSMakeSize(200, 180)];
[myCollectionView setMaxItemSize:NSMakeSize(280, 250)];
Ihre Max-Größe groß genug, um gut aussehen sollte und genügend Platz zum Dehnen der Collection-Breite passen.
Wenn Sie eine feste Anzahl von Spalten haben, können Sie wahrscheinlich verwenden (0,0), aber wenn Sie eine dynamische Anzahl von Zeilen und Spalten wollen, wie ich wollte .. sollen Sie eine feste min-Größe und einen größeren max .Size.
Während Sie eine Sammlung Ansicht bekommen könnte verhalten, wie Sie wollen, ich glaube, Sie ein Design-Problem haben
Sie sollten eine NSTableView
verwenden und Spalten 1 und ihre Dimensionierung alles andere als „None“. NSTableView
für tabellarische Daten bestimmt, und es können Zellen recyceln, die für große Menge von Elementen eine große Leistungssteigerung gibt. NSCollectionView
ist mehr wie ein Layout, das linear anordnet Elemente in einem Raster mit vertikalen Scrollen. Es ist nützlich, wenn die Spaltennummer dynamisch weitere Elemente auf dem Bildschirm zu ermöglichen ändern kann gezeigt, in der Regel je nach Ausrichtung des Geräts und Bildschirmgröße.