Ячейка NSCollectionView не подходит для рамки представления коллекции при изменении размера окна
Я использую настраиваемый макет потока для своего
NSCollectionView.
Проблема в том
override func layoutAttributesForElements(in rect: CGRect) -> [NSCollectionViewLayoutAttributes]
который правильно вычисляет ширину ячейки до и после перезагрузки.
Но ячейка не помещается в рамку представления коллекции при первой загрузке и при изменении размера окна. Но если я нажму кнопку перезагрузки, тогда ячейки идеально подходят для рамки просмотра коллекции. Но когда я изменяю размер окна
layoutAttributesForElements
вызывается, но размер ячеек не изменяется. См. Приложенный снимок экрана.
Код:
NSCollectionViewFlowLayout:
class Layout: NSCollectionViewFlowLayout{
override func awakeFromNib() {
super.awakeFromNib()
self.scrollDirection = .horizontal
minimumLineSpacing = .zero
minimumInteritemSpacing = .zero
}
override func layoutAttributesForElements(in rect: CGRect) -> [NSCollectionViewLayoutAttributes]
{
let defaultAttributes = super.layoutAttributesForElements(in: rect)
if defaultAttributes.isEmpty {
return defaultAttributes
}
var leftAlignedAttributes = [NSCollectionViewLayoutAttributes]()
var xCursor = self.sectionInset.left // left margin
var lastYPosition = defaultAttributes[0].frame.origin.y // if/when there is a new row, we want to start at left margin
var lastItemHeight = defaultAttributes[0].frame.size.height
let width = collectionView!.frame.width/5
for attributes in defaultAttributes
{
// copy() Needed to avoid warning from CollectionView that cached values are mismatched
guard let newAttributes = attributes.copy() as? NSCollectionViewLayoutAttributes else {
continue;
}
if newAttributes.frame.origin.y > (lastYPosition + lastItemHeight)
{
// We have started a new row
xCursor = sectionInset.left
lastYPosition = newAttributes.frame.origin.y
}
print(width)
newAttributes.frame.size.width = width
newAttributes.frame.origin.x = xCursor
xCursor += newAttributes.frame.size.width + minimumInteritemSpacing
lastItemHeight = newAttributes.frame.size.height
leftAlignedAttributes.append(newAttributes)
}
return leftAlignedAttributes
}
}
NSCollectionViewItem:
class Cell: NSCollectionViewItem{
static let identifier: NSUserInterfaceItemIdentifier = NSUserInterfaceItemIdentifier(rawValue: "Cell")
override func loadView() {
view = NSView()
view.wantsLayer = true
}
}
ViewController:
class ViewController: NSViewController, NSCollectionViewDelegate, NSCollectionViewDataSource {
@IBOutlet weak var collectionView: NSCollectionView!
var colors: [NSColor] = [
#colorLiteral(red: 0.4745098054, green: 0.8392156959, blue: 0.9764705896, alpha: 1),
#colorLiteral(red: 0.5568627715, green: 0.3529411852, blue: 0.9686274529, alpha: 1),
#colorLiteral(red: 0.9098039269, green: 0.4784313738, blue: 0.6431372762, alpha: 1),
#colorLiteral(red: 0.9568627477, green: 0.6588235497, blue: 0.5450980663, alpha: 1),
#colorLiteral(red: 0.9764705896, green: 0.850980401, blue: 0.5490196347, alpha: 1)
]
override func viewDidLoad() {
super.viewDidLoad()
collectionView.register(Cell.self, forItemWithIdentifier: Cell.identifier)
}
override func viewDidAppear() {
super.viewDidAppear()
collectionView.reloadData()
}
func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
return colors.count
}
func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
let cell = collectionView.makeItem(withIdentifier: Cell.identifier, for: indexPath) as! Cell
cell.view.layer?.backgroundColor = colors[indexPath.item].cgColor
return cell
}
@IBAction func actionReload(_ sender: NSButton) {
collectionView.reloadData()
}
}
Скриншот:
Перед тем, как нажать кнопку «Перезагрузить» и «Первая загрузка»: <img alt="Перед перезагрузкой" src="https://i.stack.imgur.com/MOcFB.png"/>
После нажатия кнопки перезагрузки: <img alt="введите описание изображения здесь" src="https://i.stack.imgur.com/4Gilg.png"/>
Клетка
width
то же самое до и после нажатия кнопки «Обновить». Единственная проблема с перезагрузкой представления коллекции. Мне не нужна кнопка перезагрузки. Вместо этого ячейка должна соответствовать виду коллекции.
frame.width
при первой загрузке и при изменении размера окна. Может ли кто-нибудь помочь найти решение?