Полная ширина NSCollectionViewFlowLayout с NSCollectionView
У меня есть NSCollectionViewFlowLayout
который содержит следующее:
- (NSSize) itemSize
{
return CGSizeMake(self.collectionView.bounds.size.width, kItemHeight);
} // End of itemSize
- (CGFloat) minimumLineSpacing
{
return 0;
} // End of minimumLineSpacing
- (CGFloat) minimumInteritemSpacing
{
return 0;
} // End of minimumInteritemSpacing
Я попытался сделать адаптивный макет (установить ширину при изменении размера). Я попытался добавить следующее:
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(onWindowDidResize:)
name: NSWindowDidResizeNotification
object: nil];
- (void) onWindowDidResize: (NSNotification*) notification
{
[connectionsListView.collectionViewLayout invalidateLayout];
} // End of windowDidResize:
И это прекрасно работает, если я расширяю представление коллекции (изменяю размер больше). Но если я попытаюсь свернуть представление (изменить размер меньше), я получу следующие исключения:
The behavior of the UICollectionViewFlowLayout is not defined because:
The item width must be less than the width of the UICollectionView minus the section insets left and right values, minus the content insets left and right values.
The relevant UICollectionViewFlowLayout instance is <TestListLayout: 0x106f70f90>, and it is attached to <NSCollectionView: 0x106f76480>.
Любые предложения о том, как я могу решить эту проблему?
ПРИМЕЧАНИЕ 1. Это macOS, а не iOS (хотя в сообщении об ошибке указано UICollectionViewFlowLayout).
ПРИМЕЧАНИЕ 2: Несмотря на то, что я получаю предупреждение / ошибку, ширина компоновки работает, но я хотел бы выяснить основную проблему.
1 ответ
У меня была та же проблема, но в моем случае я изменил размер представления. Решение @Giles не работало для меня, пока я не изменил контекст недействительности
class MyCollectionViewFlowLayout: NSCollectionViewFlowLayout {
override func shouldInvalidateLayout(forBoundsChange newBounds: NSRect) -> Bool {
return true
}
override func invalidationContext(forBoundsChange newBounds: NSRect) -> NSCollectionViewLayoutInvalidationContext {
let context = super.invalidationContext(forBoundsChange: newBounds) as! NSCollectionViewFlowLayoutInvalidationContext
context.invalidateFlowLayoutDelegateMetrics = true
return context
}
}
Надеюсь, это поможет кому-то, так как мне потребовалось несколько вечеров, чтобы найти решение
Исходный код, который я разместил в вопросе, работает нормально с macOS 10.14 без проблем. Я добавил следующее в свое окно, которое отображает коллекцию.
// Only Mojave and after is resizable. Before that, a full sized collection view caused issues as listed
// at https://stackru.com/questions/48567326/full-width-nscollectionviewflowlayout-with-nscollectionview
if(@available(macOS 10.14, *))
{
self.window.styleMask |= NSWindowStyleMaskResizable;
} // End of macOS 10.14+
Это потому, что вы используете событие didResize, что слишком поздно. Ваши предметы слишком широки в тот момент, когда окно начинает уменьшаться. Попробуйте использовать:
func shouldInvalidateLayout(forBoundsChange newBounds: NSRect) -> Bool {
return true
}
... при переопределении макета потока, чтобы все пересчитать.