Binding and Custom Controls

Discussion in 'Mac Programming' started by zedLondon, Jul 24, 2007.

  1. macrumors member

    Joined:
    Jun 25, 2007
    Location:
    London
    #1
    Well I've got much further along with myFirstCocoaApp™ and have now run into a bit of a problem with regards to a custom controller I'm working on and how to get it to display the correct info.

    The data model set up is as follows

    There are two array controllers A & B where B sets it's content array based on A.

    I have a TableView displaying two of the properties of the objects in B (they're NSManagedObjects) and then have a number of text fields displaying all the properties.

    What I'd like to do is replace the text fields with a single custom NSView subclass that displays all the property strings of the selected NSManagedObject with specific formatting.

    Now at the moment what I'm thinking of doing is using

    Code:
    - (void)observeValueForKeyPath:(NSString *)keyPath 
    ofObject:(id) object 
    change:(NSDictionary *)change 
    context:(void *)context
    
    and the addObserver: etc. to observe whenever NSArrayController B changes it's contents.

    As far as I can make out I can only get the whole array from NSArrayController using -selectedObjects and reading that into an array.

    So far so good. But how do I get it to change the selected object within that array based on the selection in the tableView?

    I've got something working where my custom class gets the selected row number from the tableView and then looks that up in the array populated from B. But this requires an action to be triggered from a button. How can I get it to update whenever the user changes the selection in the table view?

    Thanks in advance guys
     
  2. macrumors G4

    Eraserhead

    Joined:
    Nov 3, 2005
    Location:
    UK
    #2
    If the objects represented in the two arrayControllers are connected by a relationship, then you can bind the ContentSet of the second arrayController to the appropriate relationship of the selected object in the first.

    If it's more complex than that you can use: -(void)tableViewSelectionDidChange:(NSNotification *)notification in the delegate of the tableView
     
  3. thread starter macrumors member

    Joined:
    Jun 25, 2007
    Location:
    London
    #3
    The two array controllers are already bound. B gets it's contentArray Dependent on the selection in A. The table is bound to arrayController B. So it doesn't have a delegate. The table only shows two of the properties of the objects in arrayController B and I want my custom control to show all of the properties of the object selected in the tableView. And I want to it to update whenever the selction in the table changes

    I've looked at making my object complient to Bindings, but that seems like a lot of work, and was just wondering if anyone had an easier solution
     
  4. macrumors 6502

    Joined:
    Mar 31, 2005
    Location:
    London, England
    #4
    Why don't you just observe the array controller's "selectedObjects" property? If the table view is bound to that array controller, then its selection will always match that of the table.
     
  5. macrumors G4

    Eraserhead

    Joined:
    Nov 3, 2005
    Location:
    UK
    #5
    Right, so tableViewSelectionDidChange is the one to use because Nutter is completely right when he says:
    Personally in D&D Manager I use a mix of updating like this and bindings, which seems to work pretty well.

    However I have tabs too so I call an updater method from -(void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem as well as tableViewSelectionDidChange.
     
  6. thread starter macrumors member

    Joined:
    Jun 25, 2007
    Location:
    London
    #6
    That's what i want to do, but doesn't the selectedObjects property retunt an array of the currently selected content array? Or am i misreading the documentation?

    Does it return an array of objects selected in the tableView? If it does that would be brilliant!
     
  7. macrumors G4

    Eraserhead

    Joined:
    Nov 3, 2005
    Location:
    UK
    #7
    You can get the array of objects selected with [arrayController selectedObjects], this certainly works with tableViewSelectionDidChange
     
  8. thread starter macrumors member

    Joined:
    Jun 25, 2007
    Location:
    London
    #8
    Ok just to clear up my understanding. By selected objects, does that mean the content array of controllerB based on it's binding with A

    so if A contains a list of languages and B contains a list of words then due to the binding if I select language1 from A then B's content array changes to be words from language1. Then tableview displays all these words. (well two properties of the words)

    So if language1 is selected does [arrayControllerB selectedObjects] return the full contents of B at that time (all the words in language1) or does it return the single word that is selected in the tableView?

    And if it's the latter and I use tableViewSelectionDidChange do I have to implement all the tableView Delegate methods?

    PS Eraserhead the D&D manager looks cool! I'm actually building a tool to help building conlangs. The aim is to have a searchable dictionary for each language, a word generator (which i have working) where you can vary the parameters by language and a sound change applier (with sound change rules for each language). The idea being you can define wordlists for a parent language and then apply the sound changes to come up with correspondent words in different daughter languages.
     
  9. macrumors G4

    Eraserhead

    Joined:
    Nov 3, 2005
    Location:
    UK
    #9
    not really [arrayControllerA selectedObjects] returns the objects selected in arrayControllerA.

    FWIW You use the contentSet binding to link them.

    So if language1 is selected does [arrayControllerB selectedObjects] return the full contents of B at that time (all the words in language1) or does it return the single word that is selected in the tableView?[/quote]
    This returns the object selected in arrayControllerB's table, you use [arrayControllerB arrangedObjects] to get the full contents of arrayControllerB.

    No, just the ones you want.

    Thanks :).
     
  10. thread starter macrumors member

    Joined:
    Jun 25, 2007
    Location:
    London
    #10
    This returns the object selected in arrayControllerB's table, you use [arrayControllerB arrangedObjects] to get the full contents of arrayControllerB.

    Fantastic! I'd misunderstood what the selectedObjects does.

    Have the bindings working thanks, I must have used contentSet, just don't have it in front of me and can't always remember the names of all the functions/paramerters .. yet ;)

    Thanks again!
     

Share This Page