views:

177

answers:

3

I've been using CGContextSetShadowWithColor() in my Quartz drawing code on the iPhone to generate the "stomped in" look for text and other things (in drawRect: and drawLayer:inContext:).

Worked perfectly, but when running the exact same code against iOS 3.2 and now iOS 4.0 I noticed that the shadows are all in the opposite direction. E.g. in the following code I set a black shadow to be 1 pixel above the text, which gave it a "pressed in" look, and now this shadow is 1px below the text, giving it a standard shadow.

...
CGContextSetShadowWithColor(context, CGSizeMake(0.f, 1.f), 0.5f, shadowColor);
CGContextShowGlyphsAtPoint(context, origin.x, origin.y, glyphs, length);
...

Now I don't know whether I am (or have been) doing something wrong or whether there has been a change to the handling of this setting. I haven't applied any transformation that would explain this to me, at least not knowingly. I've flipped the text matrix in one instance, but not in others and this behavior is consistent. Plus I wasn't able to find anything about this in the SDK Release Notes, so it looks like it's probably me. What might be the issue?

A: 

It's a bug they didn't get around to fixing, it seems. :)

Jonathan Grynspan
+1  A: 

So it seems to be either a bug or intentional by Apple; either way in order to solve this I'm now using a UIView category. I set the shadow Y direction as it should be on iOS 3.2+, but as long as I'm supporting iOS < 3.2 I'll be using the following class method to multiply the direction either by 1 or -1, as needed by the device:

...
CGContextSetShadowWithColor(context, CGSizeMake(0.f, [UIView shadowVerticalMultiplier] * -1.f), 0.5f, textShadowColor);
...

Here's the category:

@interface UIView (shadowBug) 

+ (NSInteger) shadowVerticalMultiplier;    

@end


@implementation UIView (shadowBug)

+ (NSInteger) shadowVerticalMultiplier
{
    static NSInteger shadowVerticalMultiplier = 0;
    if (0 == shadowVerticalMultiplier) {
        CGFloat systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
        shadowVerticalMultiplier = (systemVersion < 3.2f) ? -1 : 1;
    }

    return shadowVerticalMultiplier;
}


@end
Pascal
A: 

iOS 4.0 has this same change in behavior (I found my way here by searching on CGContextSetShadow while updating my iPhone app for 4.0). So, apparently CGContextSetShadow behaves one way if you link against iPhone OS 3.1.3 and before, and a different way if you link against iPhone OS 3.2 or later.

matt
Exactly. Good thing is you can simply check if the current device runs < 3.2 and act accordingly, as I did in my category, so at least this is consistent.
Pascal
It seems even if you link against an older SDK the reversal happens – see the Facebook App's reversed shadows!
coob