Re: What is the best way to store some kind of identifying string in an interface builder object?
On 6/18/09 2:52 PM, Greg Guerin said: Chilton Webb wrote: Is there a way to add a tag an IB object in such a way that it is not visible to the user, but in such a way that I could reference it from my app? Maybe the -tag method: it returns a 32-bit integer.. It's settable in IB as the control's tag value. I don't know if iPhone has it. Since it's only 32-bits I don't know how useful it would be for your intended purpose. But IB has no inherent use for it, and it is readable from the app. Note that 'tag' is 64 bit in 64 bit apps. -- Sean McBride, B. Eng s...@rogue-research.com Rogue Researchwww.rogue-research.com Mac Software Developer Montréal, Québec, Canada ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: What is the best way to store some kind of identifying string in an interface builder object?
On 19/06/2009, at 3:59 AM, Erik Buck wrote: use [[myBox subviews] makeObjectPerformSelector:@selector(setEnabled:) withObject:NO]; or similar. Are you certain that works? 'NO' isn't an object, so I didn't think you could use -makeObjectsPerformSelector:withObject: in this fashion - or is there some magic available that isn't mentioned in the docs? The docs appear to state explicitly that the single argument to the selector must be type id. However it does seem to compile without complaint, though I'm not sure why... If this is permitted, does it work with rects, points, etc? Alternatively you can use: [[box subviews] setValue:[NSNumber numberWithBool:NO] forKey:@enabled]; since KVC converts to scalars as needed. Another problem here is that setEnabled: only works on NSControls or derivative, not NSViews. So you'd have to be certain that all your subviews were controls, otherwise it will throw with an unknown property error when it hits the first non-control view. Or you could implement -setEnabled for NSView in a category. --Graham ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: What is the best way to store some kind of identifying string in an interface builder object?
On 19/06/2009, at 5:23 PM, Graham Cox wrote: However it does seem to compile without complaint, though I'm not sure why... If this is permitted, does it work with rects, points, etc? My bad - it doesn't even compile in fact, so I guess that answers that question. --Graham ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: What is the best way to store some kind of identifying string in an interface builder object?
It compiles because NO == nil == NULL == 0. I shouldn't have posted the silly example which doesn't work in most cases. how about this typed in mail: @interface NSView (MYGroupEnable) /// Enable all controls nested within the receiver - (void)enableSubviews { for(NSView *currentView in [self subviews]) { if([currentView respondsToSelector:@selector(setEnabled:)]) { [currentView setEnabled:YES]; } else { [currentView enableSubviews]; } } } /// Disable all controls nested within the receiver - (void)disableSubviews { for(NSView *currentView in [self subviews]) { if([currentView respondsToSelector:@selector(setEnabled:)]) { [currentView setEnabled:NO]; } else { [currentView disableSubviews]; } } } @end On Jun 19, 2009, at 3:23 AM, Graham Cox wrote: On 19/06/2009, at 3:59 AM, Erik Buck wrote: use [[myBox subviews] makeObjectPerformSelector:@selector(setEnabled:) withObject:NO]; or similar. Are you certain that works? 'NO' isn't an object, so I didn't think you could use -makeObjectsPerformSelector:withObject: in this fashion - or is there some magic available that isn't mentioned in the docs? The docs appear to state explicitly that the single argument to the selector must be type id. However it does seem to compile without complaint, though I'm not sure why... If this is permitted, does it work with rects, points, etc? Alternatively you can use: [[box subviews] setValue:[NSNumber numberWithBool:NO] forKey:@enabled]; since KVC converts to scalars as needed. Another problem here is that setEnabled: only works on NSControls or derivative, not NSViews. So you'd have to be certain that all your subviews were controls, otherwise it will throw with an unknown property error when it hits the first non-control view. Or you could implement -setEnabled for NSView in a category. --Graham ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: What is the best way to store some kind of identifying string in an interface builder object?
Hi, Here's why I'm asking. Right now I have an app that has a number of possibly different 'objects' in it. And I currently have a single inspector for all of them. When a new object is selected, the appropriate view for that object is added to the inspector window. This is a basically okay design. The problem is that for any new object I add, I have to... 1) Add the object code, which contains all of the names of all of the things I want in it 2) Add the inspector view controller code, which contains all of the same names 3) Add the inspector view xib, which contains zero same names, so I need to physically wire up all of the fields to things with the right names. If I had a way of tagging the objects by name inside XCode, then I could actually whittle this down to a single object file, that would use the keys found on the objects themselves (title, settings, etc.) as tags for saving/restoring their state from files, as well as knowing what properties to change on the objects. This would eliminate over 80% of the code I currently have to write, and duplicate, for each object. And those object files are HUGE. This would also mean that to use one of these objects in another app, all the other app would need would be a fairly generic interface to the object. -Chilton ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: What is the best way to store some kind of identifying string in an interface builder object?
If I understand correctly: * You want to have a single general-purpose model class (what you are calling the object) for which different object types might have different sets of attributes. Kind of like a dictionary or an NSManagedObject. * You'd like to use xib files to serve as attribute specification files, using the fact that they already implicitly know what attributes that type of object has by virtue of the UI controls that are in that inspector. * You'd like a single general-purpose controller class that knows how to derive the attribute specification from the xib file, and interacts with your general-purpose model class accordingly. * The object types have lots of attributes and/or there are lots of different types, so it's tedious to write boilerplate code every time you add an object type. First thought: you could use the NSMatrix hack I described earlier to construct the kind of xibs you want. It would let you map arbitrary strings to arbitrary objects in the xib. Second thought: you could use some sort of code generator, either Kevin Callahan's Accessorizer or a script you write yourself to help write model classes (and not try to have a single general-purpose model class). Third thought: in IB, you could assign bindings to all the UI components -- this seems a natural thing to do regardless -- and somewhere in your code you could iterate through all subviews of that inspector view and derive attribute names by parsing the bindings. This is assuming it's possible to ask a view what its bindings are, which I don't know how to do offhand. Anyway, a text field might have a binding inspectedObject.title and that's how you'd know there's a title attribute. --Andy On Friday, June 19, 2009, at 03:35PM, Chilton Webb chil...@mac.com wrote: Hi, Here's why I'm asking. Right now I have an app that has a number of possibly different 'objects' in it. And I currently have a single inspector for all of them. When a new object is selected, the appropriate view for that object is added to the inspector window. This is a basically okay design. The problem is that for any new object I add, I have to... 1) Add the object code, which contains all of the names of all of the things I want in it 2) Add the inspector view controller code, which contains all of the same names 3) Add the inspector view xib, which contains zero same names, so I need to physically wire up all of the fields to things with the right names. If I had a way of tagging the objects by name inside XCode, then I could actually whittle this down to a single object file, that would use the keys found on the objects themselves (title, settings, etc.) as tags for saving/restoring their state from files, as well as knowing what properties to change on the objects. This would eliminate over 80% of the code I currently have to write, and duplicate, for each object. And those object files are HUGE. This would also mean that to use one of these objects in another app, all the other app would need would be a fairly generic interface to the object. -Chilton ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: What is the best way to store some kind of identifying string in an interface builder object?
On 20/06/2009, at 5:35 AM, Chilton Webb wrote: Hi, Here's why I'm asking. Right now I have an app that has a number of possibly different 'objects' in it. And I currently have a single inspector for all of them. When a new object is selected, the appropriate view for that object is added to the inspector window. This is a basically okay design. The problem is that for any new object I add, I have to... 1) Add the object code, which contains all of the names of all of the things I want in it 2) Add the inspector view controller code, which contains all of the same names 3) Add the inspector view xib, which contains zero same names, so I need to physically wire up all of the fields to things with the right names. If I had a way of tagging the objects by name inside XCode, then I could actually whittle this down to a single object file, that would use the keys found on the objects themselves (title, settings, etc.) as tags for saving/restoring their state from files, as well as knowing what properties to change on the objects. This would eliminate over 80% of the code I currently have to write, and duplicate, for each object. And those object files are HUGE. This would also mean that to use one of these objects in another app, all the other app would need would be a fairly generic interface to the object. This sounds - maybe - like a situation I have in my current app. I have a master-detail interface that serves as an inspector. There are a number of different object types that can be inspected, currently around 15. If the number of types were to go substantially higher than this this approach might not be so scalable, but right now it works out well. Each type requires a different UI to edit it. Some types derive from others so in many cases there is a commonality in the UI, and ultimately all objects have a common ancestor. For each object type, I have a distinct controller class, and the class hierarchy for the controllers mimics the object class hierarchy - there is a controller common ancestor too. This common ancestor has a 'view' property which is an outlet to a complete view containing all of the individual controls. Each control within the view has an outlet in the controller and an associated action. In the nib, all the controllers and all of the views are created and wired up. The views are standalone custom views, not at this stage part of any window. There is a master controller (in fact File's Owner, a NSWindowController subclass) that has outlets to each of the individual controllers, as well as an outlet to a host view within the main window into which the required detail view will be inserted as necessary when the right object type is selected. So far, it's all quite normal, there's no getting away from the need to wire up all the individual outlets and actions to all the individual controllers and their controls. But the goal was to minimise the amount of code you have to write to make it all work, right? So here's the clever bit. Each outlet to the detail controllers is named according to the class of the object it represents, so given an object of a certain class becoming selected, the outlet name can be discovered using some simple string manipulation on the class name. The appropriate subcontroller can then be returned using KVC, and so it's 'view' property can be found and installed into the host view. The master controller keeps track of the current subcontroller so it can also remove the installed view later when a new object type is selected. So installing the relevant UI and its controller is a very small amount of generic code. The next thing is to ensure that the controls thus shown are connected to the relevant properties of the selected object. For this, I use KVO, but bindings would work too and be even less code. The installed detail controller is given a reference to the selected object and immediately becomes an observer of it (a KVO observer that is). In its implementation of -observeValueForKeyPath:ofObject:change:context:, it invokes [self setValue:forKeyPath:] for the key path. The controller has setter methods which identically match the properties of the observed object, but simply set the appropriate control values/states as needed. The action methods do the inverse - setting the properties of the object in response to the controls. In order to know what properties should be observed, the objects implement a simple class protocol whereby they return a list of properties on request. The controllers can then iterate over the list and become an observer for each one - again making this a generic write-just-once proposition. So, each controller has to implement an action and a setter for each control/property, but typically they are very minimal one-line methods. Using bindings you could eliminate the need for that part,
What is the best way to store some kind of identifying string in an interface builder object?
Hi, In an effort to create a less structured set of IB objects, I would like to 'tag' various IB elements. For example, I might want to add a specific tag to a group of objects that I might later want to show or hide. I might want to grab values from only objects that contain some key word. And I might want to add or remove objects to the window at runtime, that won't be in the IB file to begin with. I'd rather not have to keep creating instance variables and writing glue code to do this. And I'd prefer to not use bindings for this, since I'd ultimately like to use this same technique on the iPhone. I could use the 'help' tag in OSX, but that's visible to the user. I could use the 'Interface Builder Identity' tag on the iPhone side, but that's AFAIK just used in IB itself. Is there a way to add a tag an IB object in such a way that it is not visible to the user, but in such a way that I could reference it from my app? Thank you, -Chilton Webb ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: What is the best way to store some kind of identifying string in an interface builder object?
See the - (void)setRepresentedObject:(id)anObject method of NSCell. You can set a string or dictionary and the represented object and retrieve it via -representedObject. You can also instantiate an array and add objects to the array within IB. Then you only need an outlet instance variable to reference the array and not separate instance variables for all of the user interface objects. See Foundation Collections Palette You can populate the array entirely within IB. Make any target/action connections in IB. http://www.geocities.com/kritter_cocoadev/ For some final advice: Don't do what you are contemplating. Users hate interfaces that change outside the user's control. If a group of objects are going to appear or disappear, consider whether they should become enabled or disabled instead. If objects are logically associated, group the objects together visibly in boxes or matrix or tabs or through other means. Then you can enable or disable all elements of the box in code without needing to have outlets for every element. You can even hide or unhidden the whole box. use [[myBox subviews] makeObjectPerformSelector:@selector(setEnabled:) withObject:NO]; or similar. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: What is the best way to store some kind of identifying string in an interface builder object?
On Thu, Jun 18, 2009 at 1:59 PM, Erik Buckerik.b...@sbcglobal.net wrote: You can also instantiate an array and add objects to the array within IB. Then you only need an outlet instance variable to reference the array and not separate instance variables for all of the user interface objects. See Foundation Collections Palette You can populate the array entirely within IB. Make any target/action connections in IB. http://www.geocities.com/kritter_cocoadev/ Since the last update on that page is from the Panther era, and since Leopard's IB3 completely broke backwards compatibility with IB2 plugins, I'd say the chances of the Foundation Collections Palette still working are approximately zero. Mike ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: What is the best way to store some kind of identifying string in an interface builder object?
On Thu, Jun 18, 2009 at 1:45 PM, Michael Ashmichael@gmail.com wrote: Since the last update on that page is from the Panther era, and since Leopard's IB3 completely broke backwards compatibility with IB2 plugins, I'd say the chances of the Foundation Collections Palette still working are approximately zero. I started working on replacements but they never got anywhere. Please file an enhancement request; this could be very useful. --Kyle Sluder ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: What is the best way to store some kind of identifying string in an interface builder object?
Chilton Webb wrote: Is there a way to add a tag an IB object in such a way that it is not visible to the user, but in such a way that I could reference it from my app? Maybe the -tag method: it returns a 32-bit integer.. It's settable in IB as the control's tag value. I don't know if iPhone has it. Since it's only 32-bits I don't know how useful it would be for your intended purpose. But IB has no inherent use for it, and it is readable from the app. -- GG ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: What is the best way to store some kind of identifying string in an interface builder object?
Hi Greg! Thanks for writing back. On Jun 18, 2009, at 4:52 PM, Greg Guerin wrote: Is there a way to add a tag an IB object in such a way that it is not visible to the user, but in such a way that I could reference it from my app? Maybe the -tag method: it returns a 32-bit integer.. It's settable in IB as the control's tag value. I don't know if iPhone has it. Since it's only 32-bits I don't know how useful it would be for your intended purpose. But IB has no inherent use for it, and it is readable from the app. It *would* be useful, but IB doesn't let you set it to a string in Cocoa. It's limited to numeric values, which makes it less useful for humans. For a bit of perspective, this is doable in *CARBON* apps, via the 'Command' attribute in Interface Builder. You can only use 4 characters, but it's damned useful. It's commonly used to create interfaces that don't require hard linkage between the code and the view. Somewhat ironically, despite that MVC is the law of the land in Cocoa, this option is not available to Cocoa apps. I was sure I was mistaken about this! Any other suggestions? Thanks! -Chilton ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: What is the best way to store some kind of identifying string in an interface builder object?
Chilton Webb wrote: It *would* be useful, but IB doesn't let you set it to a string in Cocoa. It's limited to numeric values, which makes it less useful for humans. For a bit of perspective, this is doable in *CARBON* apps, via the 'Command' attribute in Interface Builder. You can only use 4 characters, but it's damned useful. It's commonly used to create interfaces that don't require hard linkage between the code and the view. Somewhat ironically, despite that MVC is the law of the land in Cocoa, this option is not available to Cocoa apps. I was sure I was mistaken about this! Any other suggestions? Create an app where you enter the 4-char text you want, and it shows you the decimal number and even puts it on the pasteboard, so you simply paste it in IB. The same app can have the inverse function: enter or paste a decimal number, see the 4-char code. This is surprisingly close to the Currency Converter illustrative app for introducing Cocoa and IB. It shouldn't be that hard to build. A useful improvement would make it work via the Services menu (read current selection as input, convert to alternate form, paste). -- GG ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: What is the best way to store some kind of identifying string in an interface builder object?
On Jun 18, 2009, at 5:15 PM, Chilton Webb wrote: Hi Greg! Thanks for writing back. On Jun 18, 2009, at 4:52 PM, Greg Guerin wrote: Is there a way to add a tag an IB object in such a way that it is not visible to the user, but in such a way that I could reference it from my app? Maybe the -tag method: it returns a 32-bit integer.. It's settable in IB as the control's tag value. I don't know if iPhone has it. Since it's only 32-bits I don't know how useful it would be for your intended purpose. But IB has no inherent use for it, and it is readable from the app. It *would* be useful, but IB doesn't let you set it to a string in Cocoa. It's limited to numeric values, which makes it less useful for humans. For a bit of perspective, this is doable in *CARBON* apps, via the 'Command' attribute in Interface Builder. You can only use 4 characters, but it's damned useful. It's commonly used to create interfaces that don't require hard linkage between the code and the view. Somewhat ironically, despite that MVC is the law of the land in Cocoa, this option is not available to Cocoa apps. I was sure I was mistaken about this! Any other suggestions? As was suggested, probably a utility app. I know when I moved one of my apps from Carbon to Cocoa, I also created IB palettes (later plugins) for all the UI. I put conversion APIs around the 'tag' attributes. I could then enter/display four- char codes. ___ Ricky A. Sharp mailto:rsh...@instantinteractive.com Instant Interactive(tm) http://www.instantinteractive.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: What is the best way to store some kind of identifying string in an interface builder object?
On Jun 18, 2009, at 4:45 PM, Michael Ash wrote: On Thu, Jun 18, 2009 at 1:59 PM, Erik Buckerik.b...@sbcglobal.net wrote: [...] You can populate the array entirely within IB. Make any target/ action connections in IB. http://www.geocities.com/kritter_cocoadev/ Since the last update on that page is from the Panther era, and since Leopard's IB3 completely broke backwards compatibility with IB2 plugins, I'd say the chances of the Foundation Collections Palette still working are approximately zero. Way back in the NextStep days, I used an NSMatrix as a sort of poor man's array. I'd drag a text field or a form into the nib, stretch it out to as many elements as I wanted, and make outlet connections from the cells to the elements of my array. I'd type descriptions of the array elements into the text fields, kind of like comments. Once the nib was loaded, it only took a few lines of code to construct a real array and discard the NSMatrix. The same approach could be used to construct a dictionary. --Andy ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com