Showing posts with label iphonesdk. Show all posts
Showing posts with label iphonesdk. Show all posts

Friday, 2 April 2010

iPhone Delete Button Image

I've just reproduced the red delete button that is used in the Contacts app and other places on the iPhone. I thought I would share it with the world.

This isn't the super-glossy button used in action sheets, but one that can appear in the bottom of a view when editing an item or looking at its details. The Contacts app and the mail account settings screen are examples of this.

click here to download the image

Use the following code to set up your button:

    [self.deleteButton setBackgroundImage:[[UIImage imageNamed:@"delete_button.png"]
                                           stretchableImageWithLeftCapWidth:8.0f
                                           topCapHeight:0.0f]
                                 forState:UIControlStateNormal];

    [self.deleteButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    self.deleteButton.titleLabel.font = [UIFont boldSystemFontOfSize:20];
    self.deleteButton.titleLabel.shadowColor = [UIColor lightGrayColor];
    self.deleteButton.titleLabel.shadowOffset = CGSizeMake(0, -1);

This will give you something like this:

This button should probably pop up an action sheet to confirm the action.

Tuesday, 11 August 2009

UITextField fuzzy/blurred text

I just solved a very obscure bug where the text in a UITextField can be rendered with a slight blur/anti-aliasing effect. The text will appear crisp when it becomes the first responder, then return to being blurred when it loses focus:

Example of blurred text

I found a number of references to this bug through Google, but everybody worked around it by playing with font sizes. After much hunting I found this thread that says anti-aliasing is applied when a view's frame contains fractional pixel values, e.g. if you calculate its size or position as a fraction of the super view.

Sure enough, casting the CGRect values to (int) for the view's frame worked perfectly. So as an example, if you wanted your text field to be centered vertically in the superview, you should use an (int) cast like this:

textFieldWidth = 300;
textFieldHeight = 31;
offsetX = 0;
offsetY = (superview.bounds.size.height - textFieldHeight) / 2;

textField.frame = CGRectMake((int) offsetX,
                             (int) offsetY,
                             (int) textFieldWidth,
                             (int) textFieldHeight);

Unfortunately, if you are trying to use UITextFields inside table view cells, you have no control over the parent cell's frame, so you might find this fix doesn't work for you if the parent view has fractional values in its frame.

Also see the post on stackoverflow.com.

Saturday, 4 July 2009

Problem with using Audio Service system sounds for playing sounds.

A lot of people are recommending using AudioServicesCreateSystemSoundID for playing short sounds on the iPhone. I think even the official SDK documentation recommends this for sounds that are just a few seconds long.

There are a couple of problems with this that you might want to consider:

  1. You cannot control the volume of the sound. As far as I can tell there is no function in the API to let you do this.
  2. When you have your phone set to vibrate, the sounds will not play, even when headphones are plugged in. This is in contrast to using AVAudioPlayer and the like which will play sounds through the headphones in vibrate mode.

So I guess using the AudioServicesCreateSystemSoundID approach only really applies for 'alert' sounds or sounds that are not crucial to your app.

Wednesday, 24 June 2009

Improve iPhone flip transition performance

If you've tried animating a UIView onto the screen using UIViewAnimationTransitionFlipFromLeft or UIViewAnimationTransitionFlipFromRight you may have noticed a slight lag in the first animation. The obvious way to implement a flip transition is with code like the following:

- (void)showFlipView {
    UIView *parentView = self.view;

    self.flipViewController.view.frame = parentView.bounds;

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft
                           forView:parentView
                             cache:YES];

    [UIView setAnimationDuration:1];
    [parentView addSubview:self.flipViewController.view];
    [UIView commitAnimations];
}

One explanation for the lag you sometimes see is that views are lazy loaded, and the delay is caused by the flip view being loaded. But even if you force the view to be loaded by accessing the controller's view property this lag can still manifest.

One way I found to stop this lag is to add the flip view to the parent view when the parent view loads, and set its hidden value to YES. Then when you want to animate it in, you set hidden to NO:


- (void)viewDidLoad {
    [super viewDidLoad];

    // ...

    self.flipViewController.view.hidden = YES;
    [self.view addSubview:self.flipViewController.view];
}

- (void)showFlipView {
    UIView *parentView = self.view;

    self.flipViewController.view.frame = parentView.bounds;

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft
                           forView:parentView
                             cache:YES];

    [UIView setAnimationDuration:1];
    self.flipViewController.view.hidden = NO;
    [UIView commitAnimations];
}

Thursday, 11 June 2009

UIWebView doesn't open target="_blank" links.

If you are using UIImageView to display external webpages, you may come across an issue where certain links don't fire UIWebViewNavigationTypeLinkClicked events. This happens when the link has the target="_blank" attribute.

To work around this problem you can inject some javascript after the page load to remove this attribute from all the links:

- (void)webViewDidFinishLoad:(UIWebView *)webView {
        NSString *js = @"\
        var d = document.getElementsByTagName('a');\
        for (var i = 0; i < d.length; i++) {\
            if (d[i].getAttribute('target') == '_blank') {\
                d[i].removeAttribute('target');\
            }\
        }\
        ";

        [webView stringByEvaluatingJavaScriptFromString:js];
}