ninjaneer
ninjaneer

Reputation: 7031

UINavigationBar woes

I'm having so many problems with this.

  1. First of all, the UINavigationBar built-in from the UINavigationController nudges the position of the rest of my UIViewControllers down (which I have to manually nudge the position back up). I've searched on stackoverflow and one suggestion says to hide the current navbar and manually add a UINavigationBar in the interface builder. Which brings me to my second problem:
  2. If I add a UINavigationBar manually through IB, the navigation becomes "disconnected", for example, the back button needs to be implemented manually to pop view controllers. Which brings me to my third problem:
  3. The specification I was given stated that it wants the back button with the shape of a back button (left of the button is slanted like a triangle). Unfortunately I've been searching everywhere and everyone is saying you'll have to manually add an image to make it look like a back button. But what if my back button title is longer than the image? I would have to make an image for each title!

Any solutions to any 3 of those problems would be extremely helpful!

Upvotes: 0

Views: 482

Answers (3)

Jano
Jano

Reputation: 63667

First problem: I use a parent view with 415 pixels because 45 (460-415) are taken by the nav bar. No need to nudge since I start with 415.

Second and third: not really. You can use a stretchable image where you draw the text. For this recipe you need a button with a left and right side, and one pixel in the middle which will be stretched to the size of the (left side + right side + length of the text in the middle).

Example: left button with 12 + 1 + (text size) + 5 pixels

left button

Then do this:

/**
 * Return the given image with white text written in the middle.
 *
 * The image should be stretchable.
 * The text is written with bold system font 12.
 *
 * @param btnLeft  The original image.
 * @param capWidth The capWidth to stretch it.
 * @param text     The text to draw in the image.
 * @return A image containing the original stretched image with some text written in the middle.
 */
+(UIImage*) drawText:(NSString*)text inImage:(UIImage*)image capWidth:(int)capWidth {

    if (image==nil) {
        return nil;
    } 

    // make it stretchable
    UIImage *stretchable = [image stretchableImageWithLeftCapWidth: capWidth
                                                      topCapHeight: 0];

    UIFont *font = [UIFont boldSystemFontOfSize:12];

    // the combined size is that of the image plus the text

    CGSize textSize = [text sizeWithFont:font];
    CGSize combinedSize = CGSizeMake(image.size.width + textSize.width, image.size.height); // should be +4 for more breath

    UIGraphicsBeginImageContext(combinedSize);

    // draw the image
    [stretchable drawInRect:CGRectMake(0,0,combinedSize.width,combinedSize.height)];

    // draw the text
    float y = (image.size.height-textSize.height)/2; // leaves even distance to top and bottom
    CGRect rect = CGRectMake(capWidth, y, textSize.width,textSize.height); // should be +2 for more breath space
    [[UIColor whiteColor] set];
    [text drawInRect:CGRectIntegral(rect) // positioning on a fractional point produces blurry text 
            withFont:font]; 

    // gets the result
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

Note that I'm using the system font, if you want something different, add another parameter. And then you add the following on the viewLoad of your controller:

// buttonLeft is the button UIImage
UIButton *back = [UIButton buttonWithType:UIButtonTypeCustom];  
UIImage *image = [ImageUtils drawText:@"Back" inImage:buttonLeft capWidth:14];    
[back setBackgroundImage:image forState:UIControlStateNormal];  
[back addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
back.frame = CGRectMake(0, 0, image.size.width, image.size.height);
UIBarButtonItem *backbi = [[[UIBarButtonItem alloc] initWithCustomView:back] autorelease];  
self.navigationItem.leftBarButtonItem = backbi;

What do we achieve with this code? perfectly sized buttons that work with any localized string, and saves you from generating 2x PNG (normal + retina) for each language supported. This is similar to the Core Graphics code UIKit uses to paint buttons with title so it's not going to slow down your UI.

Upvotes: 1

Lightygalaxy
Lightygalaxy

Reputation: 121

In XIB, You have to set Navigation Bar style and status bar style of a UIView(in UiViewController.xib) to see the actual layout.

If You want to bring down the navigation bar, then So can adjust the frame of UINavigationController view when you are going to add it on window. bUt here you have to take care of lower part of each UIViewController under UINavigationController stack.

Upvotes: 1

MiguelB
MiguelB

Reputation: 1913

That's a cascade of problems. I have a simple answer, however.

There's a nifty little property of UIViewController that's called wantsFullScreenLayout. Set it to YES for every view controller that you want to add to the navigation stack and they will ignore the fact that there is a navigation bar. Just remember to set the frames of your subviews accordingly.

This corrects your first problem. The solution to the rest should come naturally to you afterwards.

Upvotes: 0

Related Questions