Reputation: 1
I've been trying to implement a left aligned list of tokens, (NSTextField inside a box NSBox).
This is what I want to get:
I am using a NSCollectionView with Compositional Layout configured with :
The idea is that when the items get their actual field contents, autolayout constraints will automatically calculate the box width and place the items one after the other, wrapping to a new line for more items.
This never happens when the data snapshot is applied.
Instead what I get is this:
The interesting thing is that when I resize the enclosing window, the desired layout is achieved!!!
It looks like the first time the collection view is rendered using the estimated size.
Sample Code:
////
- (void)configureLayout
{
float iWW = 80;
float iHH = 16;
////////////////////
// Item Definition
NSCollectionLayoutSize *itemSize = [NSCollectionLayoutSize sizeWithWidthDimension:[NSCollectionLayoutDimension estimatedDimension:iWW]
heightDimension:[NSCollectionLayoutDimension absoluteDimension:iHH]];
NSCollectionLayoutItem *item = [NSCollectionLayoutItem itemWithLayoutSize:itemSize];
////////////////////
// Group Definition
NSCollectionLayoutSize *groupSize = [NSCollectionLayoutSize sizeWithWidthDimension:[NSCollectionLayoutDimension fractionalWidthDimension:1.0]
heightDimension:[NSCollectionLayoutDimension estimatedDimension:iHH]];
NSCollectionLayoutGroup *group = [NSCollectionLayoutGroup horizontalGroupWithLayoutSize:groupSize subitems:@[item]];
group.interItemSpacing = [NSCollectionLayoutSpacing fixedSpacing:4.0];
////////////////////
// Section Definition
NSCollectionLayoutSection *section = [NSCollectionLayoutSection sectionWithGroup:group];
NSCollectionLayoutSize *headerSize = [NSCollectionLayoutSize sizeWithWidthDimension:[NSCollectionLayoutDimension fractionalWidthDimension:1.0]
heightDimension:[NSCollectionLayoutDimension absoluteDimension:22]];
NSCollectionLayoutBoundarySupplementaryItem *sectionHeader = [NSCollectionLayoutBoundarySupplementaryItem
boundarySupplementaryItemWithLayoutSize:headerSize
elementKind:sectionHeaderElementKind
alignment:NSRectAlignmentTop];
section.boundarySupplementaryItems = @[sectionHeader];
section.contentInsets = NSDirectionalEdgeInsetsMake(2, 0, 4, 10);
section.interGroupSpacing = 4.0;
////////////////////
// Prepare Layout
collectionView.collectionViewLayout = [[NSCollectionViewCompositionalLayout alloc]initWithSection:section];
}
Upvotes: 0
Views: 644
Reputation: 611
NSCollectionViewDiffableDataSource+Private.h
(.m
file is not required)#import <Cocoa/Cocoa.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSCollectionViewDiffableDataSource (Private)
- (void)applySnapshot:(NSDiffableDataSourceSnapshot *)snapshot animatingDifferences:(BOOL)animatingDifferences completion:(void(^ _Nullable)(void))completion;
@end
NS_ASSUME_NONNULL_END
applySnapshot:animatingDifferences:
code, replace with:#import "NSCollectionViewDiffableDataSource+Private.h"
[self.dataSource applySnapshot:snapshot animatingDifferences:NO completion:^{
[self.collectionView.collectionViewLayout invalidateLayout];
}];
If you want to avoid using Private method, observe NSCollectionView
's frame using NSViewFrameDidChangeNotification
and call - [NSCollectionViewLayout invalidateLayout]
.
Upvotes: 0