Thursday, March 19, 2015

How to use NSShadow

As Apple iOS Documents mentions:

An NSShadow object may be used in one of two ways. First, it may be set, like a color or a font, in which case its attributes are applied to all content drawn thereafter—or at least until another shadow is applied or a previous graphics state is restored. Second, it may be used as the value for the NSShadowAttributeName text attribute, in which case it is applied to the glyphs corresponding to the characters bearing this attribute.

Thus, There TWO ways to implement NSShadow to your code.

1st, NSShadow could be set as attributes to all content drawn thereafter.

image
////  ShadowedRectangle.m//  NSShadowDemo////  Created by Antonio081014 on 3/18/15.//  Copyright (c) 2015 Antonio081014.com. All rights reserved.//

#import "ShadowedRectangle.h"

@implementation ShadowedRectangle

- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        self.backgroundColor = [UIColor clearColor];
    }
    return self;
}

- (void)drawRect:(CGRect)rect
{
    UIFont *font = [UIFont boldSystemFontOfSize:30.f];
    
    NSShadow *shadow = [[NSShadow alloc] init];
    shadow.shadowColor = [UIColor redColor];
    shadow.shadowBlurRadius = 0.0;
    shadow.shadowOffset = CGSizeMake(0.0, 2.0);
    
    NSDictionary *attributes = @{NSShadowAttributeName          : shadow,
                                 NSForegroundColorAttributeName : [UIColor yellowColor],
                                 NSFontAttributeName            : font,
                                 NSBackgroundColorAttributeName : [UIColor greenColor]};
    
    NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:@"Text has shadows" attributes:attributes];
    
    [attributedText drawInRect:rect];
}

@end

2nd, NSShadow could be used as the value for the NSShadowAttributeName text attribute.

// Customize the UINavigationBar Title Font.
NSShadow *shadow = [[NSShadow alloc] init];
shadow.shadowColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8];
shadow.shadowOffset = CGSizeMake(0, 1);
[[UINavigationBar appearance] setTitleTextAttributes: [NSDictionary dictionaryWithObjectsAndKeys:
                                                       [UIColor colorWithRed:245.0/255.0 green:245.0/255.0 blue:245.0/255.0 alpha:1.0], NSForegroundColorAttributeName,
                                                       shadow, NSShadowAttributeName,
                                                       [UIFont fontWithName:@"HelveticaNeue-CondensedBlack" size:21.0], NSFontAttributeName,
                                                       nil]];

While, as seen on above examples, NSShadow could be easily applied to the Text as attributes, it could be also applied to images(pixels). Example could be found here.

If you want to read more, please check out http://www.antonio081014.com.

Saturday, March 14, 2015

Customize UINavigationBar “Back Button”

Summary:

This article will try to dig a little bit about UINavigationController and UINavigationBar. The story starts with me trying customzie “Back Button” on UINavigationBar, which helps user to navigate back to precede ViewController.

Let’s start from scratch:

After creating a fresh new Xcode project with two ViewControllers(VC) on StoryBoard. User could easily navigate from one VC to another by clicking on the UIBarButtonItem on the UINavigationBar. The StoryBoard would look like the following:

image

When trying to run this simply application on iOS Simulator. User will realize the Title of Back Button on the second VC is not “First View Controller”, as it should be for most of the cases. Instead, it looks like:

image

“Back”, yes, the Title was changed by System automatically to “Back” because the Title of parent VC is too long.
If the Title of first VC is changed to “First”, then runnning application again, user would see:

image

So, when the Title of first VC is too long, the second VC will change the text of back button to “Back” automatically.
After a quick check with Reference of navigationItem of UIViewController. I could change the “back button” by using:
self.navigationItem.backBarButtonItem.title = @"Custom";
But doesn’t work at all. So another dig on this, found this:

image

So, basically it is saying the “Back Button” I wish to change is associated with Previous View Controller. Thus, the title of it should be changed in the “Parent View Controller”, not in Current View Controller. This blows my mind. Also, the reference of backBarButtonItem could be found by  “Command + Clicking” on backBarButtonItem:

image

Then, the above code was moved to the “FirstVC.m” file.
But still nothing changed. Keep digging…
Based on several answers on StackOverflow.com, I realized the property navigationItem in UIViewController is readonly. So, I use this piece of code instead:
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Custom" style:UIBarButtonItemStylePlain target:nil action:nil];
This code totally rocks.

Conclusion: 

Change backBarButtonItem in Parent ViewController. Not current ViewController.
Thanks for reading.