简体   繁体   中英

How can I access many Cocoa controls without the same number of properties or outlets?

I'm building a master-detail application in which the detail view may consist of nearly 100 fields. The model object uses an external library to access the meta data in a file and does not need 100 properties; the data is retrieved from the file and represented by a structure. The fields are identified by an enumeration and accessed using a Find(Enum) method or by using an iterator, provided by the lib, which iterates over all the fields present in the meta data.

I'd like to take advantage of the Enum/Find/iterator in the library and not have to use 100 properties with getters/setters and 100 outlets to the text fields and other controls in the UI.

Similar to an approach I've seen in a program using this library, I'd like to have one getter and one setter with a switch() based on the meta data's enumerated FieldId. Within the getter and setter I'd like to programmatically access the appropriate text field or other control in the UI to get or set the value as needed.

When the user selects a file in the master view, the getter would iterate over all the detail fields and display the values of the associated meta data field. When the user saves a file I'd need to iterate over the changed fields and call the setter with the appropriate FieldId enum.

I'm new to Cocoa/Obj-C and all I can think of is bindings - but can I bind fields to methods? Can I use the binding to pass the appropriate meta data FieldId to the getter/setter?

Would having 100 outlets actually be appropriate in this situation? Should I be considering an alternate program architecture where the fields/outlets are logically grouped and divided among several classes?

If you want to iterate through a number of views of the same type (or, with the same base type like, say, UIControl ), you can use an IBOutletCollection and iterate on the single NSArray it provides. Alternatively, if you are summoning the 100 fields from code (which would actually make much more sense), why don't you just push the views yourself into an NSMutableArray or NSMutableDictionary and have them accessed through those? Even better, if the fields should appear in the same container view, it's enough to ask that for its subviews with myContainerView.subviews to get an array.

Consider making a matrix . It's a separate kind of control that provides a two-dimensional matrix of cells of a single type. Text field cells are probably the most common.

To create a matrix in the nib editor, start with a single text field. Then, hold down option and resize it. Xcode will transform it into a matrix of text field cells; you determine how many in each dimension by your dragging.

Once you have a matrix and have connected an outlet to it, you can ask it for cells by x and y index, and you can then operate on those cells as you would a stand-alone field.

As described in one of my subsequent questions, How can I bind to values of NSDictionary sub-dictionaries in Cocoa? , I ended up pre-loading the meta data into a set of nested data structures.

I then used bindings in each field to access/display the appropriate meta data. If the meta data is modified (by editing its value in a text field, for example), I'll have a method to process the modified data structure using the API of the external library.

What brought me to ask this question originally was that I think I wanted to directly use the internal data structures or methods of the external API to get or set the data within each file. I was looking at things from the wrong point of view - programmatically accessing fields in my GUI, rather than having the GUI bound to the data in my app. I should have known better :)

Thanks for your suggestions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM