Search code examples
cocoamacoscocoa-bindings

Cocoa Bindings: Binding an NSSlider to a single value in an array


I'm working on a Cocoa application that requires several sliders that will control the values for several "channels" of data. I would like to create the the app so that all of the channel data is stored as integers in a single array. Each slider would then be bound to a single element in the array. Is this possible at all? If so do I need to use a NSMutableArray or can I get away with a standard C array?


Solution

  • You should spend a few hours with the Cocoa Bindings Programming Topics Guide. The best approach is to use an intermediate controller (like NSObjectController, NSArrayController, NSDictionaryController, or NSTreeController).

    Then contemplate: Will you always have a fixed number of channels or will you need to add/remove channels at runtime?

    Because you haven't included any description of what a channel is, how you define it (your own class or just some basic Cocoa container like a dictionary) or how it will be used, or whether you want to add / remove channels dynamically, the best I can give you is the most basic possible example.

    Simple Case

    In the simplest case (you have fixed channels and a channel is nothing more than a container for some value "foo"), use an NSDictionaryController and check the "Prepares Content" box (to create its own dictionary for storage). You'll drag an NSDictionaryController into your IB XIB. To it, you'll add keys like "channelAFoo", "channelBFoo", etc., for each of these "channels".

    Add a slider for each channel. Bind it to the dictionary controller with a controller key of "selection" (the default) and a model key path of "channelAFoo" for the channel A slider, "channelBFoo" for the channel B slider, etc.

    More Complex Case

    A more complex case would involve some mutable array (as you suspected) and an NSArrayController with that mutable array as its content. You might use a collection view (NSCollectionView/Item), where your NSCollectionViewItem prototype holds the slider (and maybe a nifty channel name, color code, etc. while you're at it). As channels are added/removed from your collection (do this through the array controller so it notes the changes), a copy of your prototype will be created (or removed) for that channel, with its controls bound to some keypath of its representedObject (an instance of your "Channel" object).

    Conclusion

    If you want more specific advice, you'll have to be a lot more specific about your design and intentions. Remember, this is an advanced Cocoa technology and you should plan to spend a lot of time reading the documentation so you understand how Bindings works. This will help you to break your question down into smaller, more specific questions (so the answers can be more reasonably focused).