1

I'm new to learning Objective-C and I have a problem with NSCollectionView which I couldn't find any ways to resolve it.

My problem is:

I wrote a button event to create a NSCollectionView named thoughtCollectionView and added onto my contentView to display NSCollectionViewItems.

When I run the simulator, items look okay, but they don't reload when I scroll.

Here's my code:

MainViewController.m

- (void)thoughtShow{

    // Add Collection View
    thoughtCollectionView = [[ThoughtCollection alloc] initWithFrame:NSMakeRect(0, 0, contentWidth, contentHeight)];
    NSCollectionViewFlowLayout *layout = [[NSCollectionViewFlowLayout alloc] init];

    [thoughtCollectionView setCollectionViewLayout:layout];
    [layout setScrollDirection:NSCollectionViewScrollDirectionVertical];
    layout.itemSize = NSMakeSize(50, 50);
    layout.minimumInteritemSpacing = 20;
    layout.sectionInset = NSEdgeInsetsMake(20, 20, 20, 20);

    [thoughtCollectionView registerClass:ThoughtItems.self forItemWithIdentifier:@"ThoughtItems"];
    thoughtScrollView = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, 0, contentWidth, contentHeight)];
    thoughtScrollView.documentView = thoughtCollectionView;
    [contentView addSubview:thoughtScrollView];

    [thoughtCollectionView reloadData];
    [thoughtCollectionView setNeedsDisplay:YES];
    [thoughtCollectionView layoutSubtreeIfNeeded];
}

MainViewController.h

@interface MainViewController : NSViewController <NSCollectionViewDelegateFlowLayout, NSCollectionViewDelegate, NSCollectionViewDataSource>
@end

ThoughtCollectionView.h

@interface ThoughtCollection : NSCollectionView <NSCollectionViewDataSource, NSCollectionViewDelegate, NSCollectionViewDelegateFlowLayout>
{
    NSMutableArray * ar;
}

@end

ThoughtCollectionView.m

@implementation ThoughtCollection

- (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath{
    ThoughtItems *item = [collectionView makeItemWithIdentifier:@"ThoughtItems" forIndexPath:indexPath];
    NSLog(@"Reloading item");
    return item;
}

- (void)collectionView:(NSCollectionView *)collectionView willDisplayItem:(nonnull NSCollectionViewItem *)item forRepresentedObjectAtIndexPath:(nonnull NSIndexPath *)indexPath{
}

- (void)collectionView:(NSCollectionView *)collectionView didEndDisplayingItem:(nonnull NSCollectionViewItem *)item forRepresentedObjectAtIndexPath:(nonnull NSIndexPath *)indexPath{
}

- (NSInteger)collectionView:(NSCollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    NSLog(@"Collection view count : %lu", [ar count]);
    return [ar count];
}

- (NSInteger)numberOfSectionsInCollectionView:(NSCollectionView *)collectionView{
    return 1;
}

-(BOOL)shouldInvalidateLayoutForBoundsChange:(NSRect)newBounds
{
    return YES;
}

- (void)viewDidMoveToWindow {

    NSLog(@"My collection View");
    self.delegate = self;
    self.dataSource = self;
    ar = [[NSMutableArray alloc] init];

    for (int n = 0; n < 1000; n++) {
        [ar addObject:@"Hello"];
    }

    [self reloadData];
    [self setNeedsDisplay:YES];
    [self layoutSubtreeIfNeeded];
}
@end

Simulator display: enter image description here

Scroll: enter image description here

ThoughtItem.m

#import "ThoughtItems.h"

@interface ThoughtItems ()

@end

@implementation ThoughtItems

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view setWantsLayer:YES];
    [self.view.layer setBackgroundColor:[[NSColor orangeColor] CGColor]];
}

@end

ThoughtItem.h

#import <Cocoa/Cocoa.h>

@interface ThoughtItems : NSCollectionViewItem

@end
Nikita Lyu
  • 67
  • 2
  • 8
  • I don't see an obvious error in your code. Therefore I tried to run it but than noticed your did not include the code for `ThoughtItems`. Can you edit your question and add it? I think it might be part of the problem. – Nef10 May 03 '17 at 05:15
  • thank you! I just added my ThoughtItems code – Nikita Lyu May 03 '17 at 06:20
  • The code is missing some more stuff to actually get an app running that displays just the collection view. But why do you embed the collection view in a scroll view? Shouldn't the CollectionView have scrolling itself? Might this be the problem that you are not scrolling within the collection view and instead scrolling a view which just contains the collection view? Can you check in the view debugger, where the frame of the collection view is after scrolling? – Nef10 May 03 '17 at 06:55
  • Could I ask what's the missing code ? >< I used storyboard to add CollectionView before, and I saw it has scrollview then clipview then Collectionview. Now I do it programmatically ,but I didn't know how to use scrollview from CollectionView itself, so I added myself. – Nikita Lyu May 03 '17 at 07:01
  • Thanks for helping me ! I found out the problem! – Nikita Lyu May 03 '17 at 09:04

1 Answers1

0

I found out that what's the problem with the CollectionItem. I have to add an Object in the ThoughtItem.xib file, then change the object class name to "ThoughtItem".

And I change -(void)viewDidMoveToWindow to a method which I can call it from MainViewController. (or create NSCollectionView in the MainViewController is a way to solve it too)

Then all the problems are solved!

Nikita Lyu
  • 67
  • 2
  • 8