Im working with NSCollectionView and NSCollectionViewItems.
I have met following problem: If I rotate an NSImageView of one of the items, and then call reloadData, updated view would be messed up. Rotation would jump to the next item, angle would be different and so.
Images and code below:
Rotation Code:
let collectionViewItem = collectionView.item(at: ip) as? LibraryViewItem
collectionViewItem?.imageView?.rotate(byDegrees: CGFloat(degree))
collectionViewItem?.model?.Rotation! += degree
collectionViewItem.reloadData()
Model:
class LibraryViewItem: NSCollectionViewItem {
// 1
var model: ImageModel? {
didSet {
guard isViewLoaded else {
print("asd")
return }
if let imageFile = model {
imageView?.image = imageFile.thumbnail
textField?.stringValue = imageFile.fileName
} else {
imageView?.image = nil
textField?.stringValue = ""
}
}
}
// 2
override func viewDidLoad() {
super.viewDidLoad()
view.wantsLayer = true
view.layer?.backgroundColor = NSColor.white.cgColor
// 1
view.layer?.borderWidth = 0.0
// 2
view.layer?.borderColor = NSColor.lightGray.cgColor
}
func setHighlight(_ selected: Bool) {
view.layer?.borderWidth = selected ? 5.0 : 0.0
}
}
Delegate metod:
func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
let item = collectionView.makeItem(withIdentifier: "LibraryViewItem", for: indexPath)
guard let collectionViewItem = item as? LibraryViewItem else {return item}
let libraryModel = itemsToShow[indexPath.item]
collectionViewItem.model = libraryModel
if let selectedIndexPath = collectionView.selectionIndexPaths.first, selectedIndexPath == indexPath {
collectionViewItem.setHighlight(true)
} else {
collectionViewItem.setHighlight(false)
}
return item
}
The NSCollectioViewItem
s are reused to improve performance by avoiding item instantiation.
NSCollectioViewItem
has a method called prepareForReuse()
which is called before reusing the item.
To fix your issue, override prepareForReuse()
and (re-)set the image rotation to zero degrees in your custom implementation.
Also, do not call collectionViewItem.reloadData()
after the rotation code.