objective-cmacoscocoaseguenscollectionviewitem

Popover segue from NSCollectionViewItem


TL;WR

What is the best way to popover-segue from a cloned view (NSCollectionViewItem)?


Good afternoon,

I'm trying to figure out how to segue from an itemPrototype, but it's not as straight-forward as I was hoping, and has tripped my up, somewhat.

I've got an NSCollectionView, with a variable number of NSCollectionViewItems, each with a button. I was hoping that all I'd need to do, to segue from the button to a small information window, would be connect that window to the button via a popover segue, but as my luck would have it, that's not how this is done.

I'm assuming that because the button on the NSCollectionViewItem prototype is cloned to populate the NSCollectionView, it's passing mixed messages to the segue, when it's being called. Specifically, I'm receiving the following error when I press one of the buttons.

*** Assertion failure in -[ProductTile presentViewController:animator:], /SourceCache/AppKit/AppKit-1348.11/Controllers/NSViewController.m:815
presentViewController:animator:: View '<ProductTile: 0x610000100ea0>{represented object: (null), view: <NSView: 0x6100001208c0> (frame {{0, 0}, {346, 216}}), selected: NO}''s view is not in a window/view hierarchy.
(
    0   CoreFoundation                      0x00007fff9688c03c __exceptionPreprocess + 172
    1   libobjc.A.dylib                     0x00007fff8dea576e objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff9688be1a +[NSException raise:format:arguments:] + 106
    3   Foundation                          0x00007fff880408cb -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195
    4   AppKit                              0x00007fff8c10413c -[NSViewController presentViewController:animator:] + 535
    5   AppKit                              0x00007fff8c10447f -[NSViewController presentViewController:asPopoverRelativeToRect:ofView:preferredEdge:behavior:] + 169
    6   AppKit                              0x00007fff8c3bf75a -[NSStoryboardPopoverSegue perform] + 402
    7   libsystem_trace.dylib               0x00007fff9451acd7 _os_activity_initiate + 75
    8   AppKit                              0x00007fff8be33fc1 -[NSApplication sendAction:to:from:] + 452
    9   AppKit                              0x00007fff8be49a56 -[NSControl sendAction:to:] + 86
    10  AppKit                              0x00007fff8be49972 __26-[NSCell _sendActionFrom:]_block_invoke + 131
    11  libsystem_trace.dylib               0x00007fff9451acd7 _os_activity_initiate + 75
    12  AppKit                              0x00007fff8be498cf -[NSCell _sendActionFrom:] + 144
    13  libsystem_trace.dylib               0x00007fff9451acd7 _os_activity_initiate + 75
    14  AppKit                              0x00007fff8be47dc3 -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 2821
    15  AppKit                              0x00007fff8bea045f -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 770
    16  AppKit                              0x00007fff8be46476 -[NSControl mouseDown:] + 714
    17  AppKit                              0x00007fff8c3b030c -[NSWindow _reallySendEvent:isDelayedEvent:] + 14125
    18  AppKit                              0x00007fff8bd3fd96 -[NSWindow sendEvent:] + 470
    19  AppKit                              0x00007fff8bd3c322 -[NSApplication sendEvent:] + 2504
    20  AppKit                              0x00007fff8bc65c78 -[NSApplication run] + 711
    21  AppKit                              0x00007fff8bbe2354 NSApplicationMain + 1832
    22  Kimochi Client                      0x0000000100006b62 main + 34
    23  libdyld.dylib                       0x00007fff939715c9 start + 1
    24  ???                                 0x0000000000000003 0x0 + 3
)

Primarily, what I'm getting from that is a sense of dread. Also, I don't really think it likes clones (must be on the dark side).

I have been looking up alternatives to creating this popover segue via a Storyboard, but it looks like this may not be a common problem (either that, or I'm still not used to the relatively small amount of developers for OS X).

Specifically, my question is: how do I "do" a popover segue from an itemPrototype? I'm definitely okay with doing this programatically, but I haven't written gui-code in Objective C before, so I'd like to know that a segue like this is definitely possible, before I try to figure it out. I don't want to end up pulling my hair out, due to a technical impossibility.

Thanks for taking the time to read this! I appreciate any information you can give me, and please let me know if I could provide more details, to make my question more clear.

Michael

Edit [2015-05-15 18:59]

To to help illustrate what I'm asking, bellow are two images; an example of my collection view, and an example of the popover segue I'd like to apply to the items in the collection view. I hope this is helpful, although I can see how it might be somewhat confusing, so please let me know if you have any questions.

CollectionView View I'd like to "popover" to any of the CollectionViewItems

Edit [2015-05-15 19:08]

The above two pictures probably don't do enough to explain what I'm hoping to achieve, so following is a representation of my end goal. Hopefully this will clarify everything.

End goal

Michael


Solution

  • Storyboards are relatively new to OS X. NSCollectionView seems to not get much love from Apple. There have been numerous reports that the combination of NSCollectionView and storyboards is buggy. So, you may be better off doing this the non-storyboard way.

    It may be simplest to connect the button to an action method on your view controller. In that action method, you can use the sender parameter to identify the button and, from there, the collection view item.

    You can then open a pop-over window. You would instantiate a view controller to load the pop-over content view from a NIB (i.e. [[MyViewController alloc] initWithNibName:@"MyPopOverContentView" bundle:nil]). You'd set the view controller's representedObject. You'd create an NSPopover and set its contentViewController to the view controller and configure its other properties. Then, you'd present it using -showRelativeToRect:ofView:preferredEdge:. You'd show it relative either to the sender or one of its ancestor views within the collection view item view.