NSCollectionView's newItemForRepresentedObject Method

  • There was some discussion on NSCollectionView's
    newItemForRepresentedObject method earlier on the list, but it didn't
    quite cover what I was looking for.  Hopefully you all can help.  To
    make a long story short, I'm trying to figure out how to modify the
    size of each view as it is added to an NSCollectionView.  Read on for
    details.

    I built my NSCollectionView in Interface Builder and this of course
    built an NSView and NSCollectionViewItem prototype in IB as well with
    all the connections already hooked up for me.

    Now I want to subclass NSCollectionView so that I can override the
    newItemForRepresentedObject method.  My intention is to modify the
    frame of each object's individual view as it is added to the
    NSCollectionView.  This requires me to look at some of the subviews
    within the view itself - which at this point are just Interface
    Builder outlets since my view was built in IB.

    When the newItemForRepresentedObject method runs, I have verified that
    I can get a reference to each view as it is created, but using the
    view's IB outlets to get to the various subviews doesn't seem to
    work.  See code below...

    - (NSCollectionViewItem *)newItemForRepresentedObject:(id)object
    {
    NSCollectionViewItem *newItem = [super
    newItemForRepresentedObject:object];
    CHMessageView *newView = (CHMessageView *)[newItem view];
    //Next line of code for some reason returns nil.
    CHMessageTextView *newTextView = [newView messageTextView];
    //More code here that is not relevant.
    return newItem;
    }

    So my next thought was to actually create my view programmatically
    rather than through IB.  Sorta like this - the problem here is that I
    don't know what to put for the view's frame in the initWithFrame method.

    - (NSCollectionViewItem *)newItemForRepresentedObject:(id)object
    {
    NSCollectionViewItem *newItem = [super
    newItemForRepresentedObject:object];
    //What do I use for the new view's frame?
    CHMessageView *newView = [[CHMessageView alloc]
    initWithFrame:NSMakeRect(?, ?, ?, ?)];
    CHMessageTextView *newTextView = [newView messageTextView];
    [newItem setView: newView];
    return newItem;
    }

    So hopefully that wasn't too confusing, but my main question is - how
    do I modify the size of each subview as it is added to the
    NSCollectionView?  Thanks everybody.  This list has been so helpful.
  • Hi,
    Correct me if I'm wrong, but I think the point of NSCollectionView is that
    each subview has the same size. So it takes the Prototype view or the view
    it gets from -newItemForRepresentedObject and resizes it to the current
    size. That makes positioning the views a lot faster; it's a little bit like
    NSMatrix in that regard.

    For differently sized views, you would have to subclass NSCollectionView and
    override its (private) subview positioning methods. Or get rid of
    NSCollectionView and make your own view using a custom CALayoutManager.

    But don't take my word for it as I have just briefly looked at this subject,
    but I plan to implement something like this, too. So if anyone has better
    ideas how to do something like NSCollectionView with differently sized views
    (like IBs "Library" palette with grouping switched on), please feel free to
    suggest something ;-)

    Cheers,
    Gernot.

    On Feb 3, 2008 2:14 PM, Carter R. Harrison <carterharrison...> wrote:

    > There was some discussion on NSCollectionView's
    > newItemForRepresentedObject method earlier on the list, but it didn't
    > quite cover what I was looking for.  Hopefully you all can help.  To
    > make a long story short, I'm trying to figure out how to modify the
    > size of each view as it is added to an NSCollectionView.  Read on for
    > details.
    >
    > I built my NSCollectionView in Interface Builder and this of course
    > built an NSView and NSCollectionViewItem prototype in IB as well with
    > all the connections already hooked up for me.
    >
    > Now I want to subclass NSCollectionView so that I can override the
    > newItemForRepresentedObject method.  My intention is to modify the
    > frame of each object's individual view as it is added to the
    > NSCollectionView.  This requires me to look at some of the subviews
    > within the view itself - which at this point are just Interface
    > Builder outlets since my view was built in IB.
    >
    > When the newItemForRepresentedObject method runs, I have verified that
    > I can get a reference to each view as it is created, but using the
    > view's IB outlets to get to the various subviews doesn't seem to
    > work.  See code below...
    >
    > - (NSCollectionViewItem *)newItemForRepresentedObject:(id)object
    > {
    > NSCollectionViewItem *newItem = [super
    > newItemForRepresentedObject:object];
    > CHMessageView *newView = (CHMessageView *)[newItem view];
    > //Next line of code for some reason returns nil.
    > CHMessageTextView *newTextView = [newView messageTextView];
    > //More code here that is not relevant.
    > return newItem;
    > }
    >
    > So my next thought was to actually create my view programmatically
    > rather than through IB.  Sorta like this - the problem here is that I
    > don't know what to put for the view's frame in the initWithFrame method.
    >
    > - (NSCollectionViewItem *)newItemForRepresentedObject:(id)object
    > {
    > NSCollectionViewItem *newItem = [super
    > newItemForRepresentedObject:object];
    > //What do I use for the new view's frame?
    > CHMessageView *newView = [[CHMessageView alloc]
    > initWithFrame:NSMakeRect(?, ?, ?, ?)];
    > CHMessageTextView *newTextView = [newView messageTextView];
    > [newItem setView: newView];
    > return newItem;
    > }
    >
    > So hopefully that wasn't too confusing, but my main question is - how
    > do I modify the size of each subview as it is added to the
    > NSCollectionView?  Thanks everybody.  This list has been so helpful.
    >
  • On Feb 3, 2008, at 5:32 AM, Gernot wrote:

    > Hi,
    > Correct me if I'm wrong, but I think the point of NSCollectionView
    > is that
    > each subview has the same size. So it takes the Prototype view or
    > the view
    > it gets from -newItemForRepresentedObject and resizes it to the
    > current
    > size. That makes positioning the views a lot faster; it's a little
    > bit like
    > NSMatrix in that regard.
    >
    > For differently sized views, you would have to subclass
    > NSCollectionView and
    > override its (private) subview positioning methods. Or get rid of
    > NSCollectionView and make your own view using a custom
    > CALayoutManager.

    There is no direct way to use CALayoutManager with a view.  And if
    you're just dealing with a one-dimensional list of items  that are
    butted up against each other, CALayoutManager is probably overkill.