Search code examples
iosobjective-calignmentbit-shiftbitmask

How to get the vertical and horizontal alignment by an integer?


I'm trying to convert an integer value to a content alignment. The integer can hold both a horizontal and a vertical alignment at the same time.

First I created an enum, which describes all possibilities (i have to use the values of android Gravity class: http://developer.android.com/reference/android/view/Gravity.html)

typedef enum{
    GravityHorizontalCenter         = 1,    // (0x00000001) 
    GravityLeft                     = 2,    // (0x00000002) 
    GravityRight                    = 5,    // (0x00000005) 
    GravityVerticalCenter           = 16,   // (0x00000010) 
    GravityTop                      = 48,   // (0x00000030) 
    GravityBottom                   = 80,   // (0x00000050) 
} GravityType;

So int alignment = GravityRight | GravityTop would be 53.

I want to check the alignment of my view-objects like this:

if ((textAlignment & GravityHorizontalCenter) == GravityHorizontalCenter){

    return NSTextAlignmentCenter;
}...

But there seems to be something missing, because for 53 the if statement textAlignment & GravityHorizontalCenter) == GravityHorizontalCenter returns True.


Solution

  • You need masks for the the Vertical and Horizontal ranges.

    typedef enum{
        GravityHorizontalCenter         = 1,    // (0x00000001) 
        GravityLeft                     = 2,    // (0x00000002) 
        GravityRight                    = 5,    // (0x00000005) 
        GravityHorizontalMask           = 7,    // (0x00000007) 
        GravityVerticalCenter           = 16,   // (0x00000010) 
        GravityTop                      = 48,   // (0x00000030) 
        GravityBottom                   = 80,   // (0x00000050) 
        GravityVerticalMask             = 112,  // (0x00000070) 
    } GravityType;
    

    Then you can do a test with:

    (textAlignment & GravityHorizontalMask) == GravityHorizontalCenter
    

    or

    (textAlignment & GravityVerticalMask) == GravityTop
    

    These values are only really suitable for direct comparison, since 5 (101 binary) and 1 (001 binary) overlap as bit masks. But since you are storing two values in the same number (the first 4 bits for the horizontal alignment, and the second 4 bits for the vertical alignment), you need a mask to isolate the range of bits that you want to compare.

    Also, you should be aware that on Android the value of LEFT (the left gravity constant) is 3 and not 2. So if your enum really needs to be compatible with Android then your GravityLeft value is probably incorrect.