20

I wonder whether it is possible to add/append another item to an existing enum type (part of a framework)?

Something like this: We have the enum type

  typedef enum {  
    UIModalTransitionStyleCoverVertical = 0,  
    UIModalTransitionStyleFlipHorizontal,
    UIModalTransitionStyleCrossDissolve,
    UIModalTransitionStylePartialCurl,
 } UIModalTransitionStyle;  

Now I want to append or add to this set an item like UIModalTransitionStyleCoverVerticalFlipped. Can something like this be accomplished?

jscs
  • 63,694
  • 13
  • 151
  • 195
user325746
  • 251
  • 1
  • 3
  • 6
  • If you have the source of the framework, you can do this and any other modifications you like. – ognian Jun 26 '10 at 13:45
  • What you want to do makes perfect sense. Unfortunately, enums cannot really be extended externally the way, for example, classes can be (via inheritance, etc. etc.). – jyoungdev Jun 26 '10 at 14:16

4 Answers4

17

You can force new element to have the same type as the enum, but you can't extend it in a subclass. header file:

extern const UIModalTransitionStyle UIModalTransitionStyleCoverVerticalFlipped;

implementation file:

const UIModalTransitionStyle UIModalTransitionStyleCoverVerticalFlipped = 10;

Make sure to give some space in case the framework is extended, so that you don't have conflicts. This is a bit of a hack, but it will get rid of compiler errors and warnings.

epooch
  • 171
  • 1
  • 3
8

To do it, you have to modify the original type definition to include the new value:

typedef enum {  
    UIModalTransitionStyleCoverVertical = 0,  
    UIModalTransitionStyleFlipHorizontal,
    UIModalTransitionStyleCrossDissolve,
    UIModalTransitionStylePartialCurl,
    UIModalTransitionStyleCoverVerticalFlipped
} UIModalTransitionStyle;

Otherwise, you can take a chance on its not working, and define it separately:

typedef enum {  
    UIModalTransitionStyleCoverVertical = 0,  
    UIModalTransitionStyleFlipHorizontal,
    UIModalTransitionStyleCrossDissolve,
    UIModalTransitionStylePartialCurl,
} UIModalTransitionStyle;

typedef enum { 
    UIModalTransitionStyleCoverVerticalFlipped =
        UIModalTransitionStylePartialCurl + 1
} ExtendedUIModalTransitionStyle;

A variable that could hold the original enumeration will usually also work perfectly fine when/if you assign the new value as well (in a typical case, it'll just be an int) -- but it's not guaranteed. At least in theory, the implementation can/could assign few enough bits to hold that enumeration that it adding more values this way wouldn't work. It could also do range checking so assigning any out of range value wouldn't be allowed. Neither of these is at all common, so from a practical viewpoint it's probably not a problem -- but from a theoretical viewpoint, nothing really guarantees that code like this will work.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • Thanks for the two possible approaches. I will go with the second one. – user325746 Jun 26 '10 at 14:53
  • @Jerry approach 2 assumes that Apple are not going to add another type(s) after UIModalTransitionStylePartialCurl in future SDK versions, of which then you would get a conflict(s). – pnizzle Jul 02 '15 at 03:29
  • @pnizzle: Yes, that's (part of) why I specifically said: "you can take a chance on its not working ..." – Jerry Coffin Jul 02 '15 at 06:34
  • in later Xcode versions (9.1) extending a enum gives you a warning `Comparison of constant 'ScannerStatusNotInitialized' (-1) with expression of type 'ScannerStatus' (aka 'enum ScannerStatus') is always false`, even tho that is not true. @pnizzle, you can define it as Flipped = UIModalTransitionStylePartialCurl + 666, to increase your chances, but you have to give up your soul :| – codrut Nov 06 '17 at 11:57
1

Maybe this can help you:

typedef NS_ENUM(NSInteger, BaseType) {
    BaseTypeCase1,
    BaseTypeCase2,
    BaseTypeSize
};

typedef NS_ENUM(NSInteger, SubType) {
    SubTypeCase1 = BaseTypeSize,
    SubTypeCase2
};

Now you can switch on SubType knowing the values are unique.

If you don't have access to BaseType, you could set SubTypeCase1 to BaseType's last item + 1.

Downside is, you can't declare a method that takes a SubType and pass to it a BaseType without getting a compiler warning. So you need to declare your methods to take NSIntegers in order silence that warning. Also, it feels weird when you need to declare a parameter of SubType and be able to pass in a BaseType.

Siamaster
  • 941
  • 12
  • 19
0

To do this you have to update the Enum declaration to include UIModalTransitionStyleCoverVerticalFlipped this values as well

typedef enum {      
 UIModalTransitionStyleCoverVertical = 0,       
 UIModalTransitionStyleFlipHorizontal,     
 UIModalTransitionStyleCrossDissolve,     
 UIModalTransitionStylePartialCurl,     
 UIModalTransitionStyleCoverVerticalFlipped 
} UIModalTransitionStyle;

so UIModalTransitionStyleCoverVerticalFlipped will be equivalent to integer constant 4

whereever you use any string constant from Enum dec. corresponding constant value get replaced so it is used to constraint the variable to hold only specified set of values only(i.e. 0 to 4) in above mentioned case

iDev
  • 23,310
  • 7
  • 60
  • 85
Anshul garg
  • 233
  • 2
  • 6