May 27, 2010

iPhone: Bug in UITextField component - setTextColor not working

I'm working on a form for an iPhone app that does real-time form validation to let the user know if they're trying to create an account with a username that already exists. To let the user know that a username is already taken, I set the UITextField textColor property to red:
#define kColorRedError [UIColor colorWithRed:1 green:0 blue:0 alpha:1.0]
//... UITextField *username = [[UITextField alloc] initWithFrame:CGRectMake(12, 14, 296, 30)];
[username setTextColor:kColorRedError];
This wouldn't update until I typed another letter into the UITextField, so quite often it would display an error when it shouldn't, and vice versa. I tried using setNeedsDisplay and some other bits of code to try to force a display update after setting the text color. Nothing worked, until I tried this:
[password setTextColor:kColorRedError];
username.text = username.text;
...Quite absurd, but forces a redraw on the component. Gotta love those Apple components ;)

April 21, 2010

iPhone: Subviews in UIButtons block the touch, unless...

If you add a UIView or other UIView subclass to a UIButton, the UIView object will block touches/clicks on the UIButton. There's a simple fix to ensure that subviews in your UIButton don't interfere. In the following case, I have a subclass of UIView that loads an image from the web (WebImage), that's created inside a subclass of UIButton:
WebImage *thumb = [[WebImage alloc] initWithFrame:CGRectMake(1, 1, 94, 94) andImageUrl:@"http://mysite.com/thumbnail.png"];
[self addSubview:thumb];
thumb.userInteractionEnabled = NO;
thumb.exclusiveTouch = NO;
[thumb release]; 
All you need to do is set userInteractionEnabled and exclusiveTouch to NO or FALSE, and the subview will no longer block your button.

April 19, 2010

iPhone: You can't have a UIView subclass named "WebView"

Good lord, this wasted half a day. I was creating a UIView subclass to hold a UIWebView, and named it "WebView". Not too abstract, right? I kept getting the following cryptic error:
*** -[WebView _isAncestorOfFirstResponder]: unrecognized selector sent to instance 0x463a7b0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[WebView _isAncestorOfFirstResponder]: unrecognized selector sent to instance 0x463a7b0'
I renamed my class "WebViewView" and no more errors. Thanks for the shitty error messages Apple!

April 14, 2010

iPhone/iTouch/iPad: Check for the ability to make a phone call

I came across a situation where I wanted to lay out different buttons in case the iDevice (iPod Touch or iPad) can run my app, but can't make a phone call. The iPhone will display a "Call Store" button, but other devices won't. For a simple check, look at the following code, which checks for the device name, and looks for "iPhone" at the beginning of the string. It's a very simple implementation, but I didn't need further detection functionality for this project.
// check iDevice model for calling capability and initially assume it's an iPhone
NSString *model= [[UIDevice currentDevice] model];
BOOL canMakeCalls = YES;
//model = @"iTouch"; // manual test for non-iPhones in simulator
if ( ![model hasPrefix:@"iPhone"] ) canMakeCalls = NO;
[model release];
Then you can conditionally display or disable UI elements depending on whether it's for the iPhone only. This can obviously be customized further and more robustly, but for something quick and easy, I hope you find it useful. Check out this blog for a much more detailed detection class.

March 19, 2010

Actionscript 3: Masking in Native 3D Issue in FP10

Today I tried to mask a Sprite that was in a container that had native 3d rotation applied - i.e. a parent Sprite had some rotationX and rotationY. The masking wasn't working, but it turns out that it was only not working because another Sprite within the same parent container had a 3D "z" value set. In order to get the masking to behave properly, I had to nest the Sprite and its mask in another Sprite, so that no sibling clips had z-positioning within the same immediate parent clip. Hopefully this little note saves someone the time it took for me to realize what the issue was.