Reputation: 26375
I have an NSCollectionView
that has 3 sections which contains colors from a color palette. I want each section to have a header view with the name of the section. At first glance, it appears to work. On launch, it looks like this:
However, as soon as I resize the window, the header text ends up drawing outside the headers (and also inside it, somehow!):
In order to have headers in the collection view, I have a header view class named CollectionHeaderView
. I register this class as a supplemental view:
[_collection registerClass:[CollectionHeaderView class]
forSupplementaryViewOfKind:@"UICollectionElementKindSectionHeader"
withIdentifier:kSupplementalView];
In the collection view's delegate, I implement the method to return the view for the supplemental element:
- (NSView *)collectionView:(NSCollectionView *)collectionView
viewForSupplementaryElementOfKind:(NSCollectionViewSupplementaryElementKind)kind
atIndexPath:(NSIndexPath *)indexPath {
NSView* result = [collectionView makeSupplementaryViewOfKind:kind
withIdentifier:kSupplementalView
forIndexPath:indexPath];
if ([kind isEqualToString:@"UICollectionElementKindSectionHeader"]) {
NSTextField* textView = ((CollectionHeaderView*)result).textField;
switch (indexPath.section) {
case 0:
[textView setStringValue:@"Bright Colors"];
break;
case 1:
[textView setStringValue:@"Pastel Colors"];
break;
case 2:
[textView setStringValue:@"Designer Colors"];
break;
}
return textView;
}
return nil;
}
Furthermore, if I resize the window, the header views do not move. The collection elements seem to flow around the headers, leaving things listed under the wrong section. And, as you can see in the second picture above, widening the window ends up leaving a gap between the right edge of the header and the right edge of the collection view.
The CollectionHeaderView
class is very simple. It just creates a text field and draws the background and the text field:
@implementation CollectionHeaderView
- (instancetype)initWithFrame:(NSRect)frameRect {
self = [super initWithFrame:frameRect];
if (self != nil) {
NSRect textFrame = frameRect;
_textField = [[NSTextField alloc] initWithFrame:textFrame];
_textField.editable = NO;
_textField.bordered = NO;
_textField.font = [NSFont fontWithName:@"Helvetica-Bold" size:14.0];
_textField.backgroundColor = [NSColor colorWithSRGBRed:0.0 green:0.0 blue:0.0 alpha:0.0];
[self addSubview:_textField];
self.identifier = kSupplementalView;
}
return self;
}
- (void)drawRect:(NSRect)dirtyRect {
[super drawRect:dirtyRect];
// Drawing code here.
NSBezierPath* fillPath = [NSBezierPath bezierPath];
[fillPath appendBezierPathWithRect:dirtyRect];
[[NSColor lightGrayColor] setFill];
[fillPath fill];
[_textField drawRect:dirtyRect];
}
@end
Have I implemented any of the above methods incorrectly? Is there any method I need to implement that I haven't?
Upvotes: 1
Views: 459
Reputation: 15598
The return value of collectionView:viewForSupplementaryElementOfKind:atIndexPath:
is the supplementary view result
.
- (NSView *)collectionView:(NSCollectionView *)collectionView
viewForSupplementaryElementOfKind:(NSCollectionViewSupplementaryElementKind)kind
atIndexPath:(NSIndexPath *)indexPath {
NSView* result = [collectionView makeSupplementaryViewOfKind:kind
withIdentifier:kSupplementalView
forIndexPath:indexPath];
if ([kind isEqual:NSCollectionElementKindSectionHeader]) {
NSTextField* textView = ((CollectionHeaderView*)result).textField;
switch (indexPath.section) {
case 0:
[textView setStringValue:@"Bright Colors"];
break;
case 1:
[textView setStringValue:@"Pastel Colors"];
break;
case 2:
[textView setStringValue:@"Designer Colors"];
break;
}
return result;
}
return nil;
}
Upvotes: 3