Back Button in navigation controller - iphone

Its a very basic question - but i could not find the answer to it anywhere.
I would like a back button like the default one that shows up in a navigation bar, but with a image in the background.
Even with customization, how to calculate the size/length of the button as per the title?
Thanks a ton for the help,in advance!
UPDATE:
Thanks guys! but the answer that i finally implemented was this:
#implementation UINavigationBar (UINavigationBarCategory)
-(void)drawRect:(CGRect)rect
{
UIColor *color = [UIColor colorWithRed:(13.0/255.0) green:(183.0/255.0) blue:(255.0/255.0) alpha:1.0];
// use a custom color for the back button which i got using the digital color meter on my nav bar image :P
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColor(context, CGColorGetComponents( [color CGColor]));
CGContextFillRect(context, rect);
self.tintColor = color;
// use a custom background image for my navigation bar
UIImage *img = [UIImage imageNamed: Navigation_img];
[img drawInRect:CGRectMake(0,0,img.size.width,img.size.height)];
}//worked satisfactorily for me
#end

Create a UIButton using your own UIImage to mimic the shape you want.
The UIImage must be a stretchable type, that is, you would set the leftCapWidth to be the size of your back arrow
Set the UIButton's title to whatever you like
Create a new UIBarButtonItem using your new button as a custom view
Set this to your navigationItems leftBarButtonItem property.
The button will automatically size to fit your title.

Use sizeWithFont: NSString method to calculate the size of the title.
See NSString UIKit Additions Reference

To find out the width of specific text, you may use following methods.
NSString *str=#"Back";
CGSize sizeOfBack = [str sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(30, CGFLOAT_MAX) lineBreakMode:UILineBreakModeWordWrap];
Let me explain above two statements.
the text that you want to have in your string.
sizewithfont method will allow you to calculate the size.
Here, sizeOfBack.width will give me the width acquired by 14System sized string.
Hope it helps to you. let me know by comments, if you have yet doubts regarding this.

Related

UIButton won't gray out

Isn't UIButton supposed to become grayish/grayer when enabled=NO ?
I have a simple UIButton on a blackbackground (no custom images, no custom nothing, just dragged it with IB and changed size and title).
And when I set it programatically to become disabled it stays white as hell!
For now I'm using a small stupid workaround: hidden blackbg 0,5 alpha UIView on top of the button that becomes hidden=NO when I need to disable the button... but I would like to set the button properly...
Any thoughts?
There is another way without having to alpha the whole button:
[startButton setTitleColor:[UIColor grayColor] forState:UIControlStateDisabled];
Then whenever you set the enabled property to NO, the button's text will automatically gray out.
There is no way to make a UIButton "grayer". But you can use that trick :
UIButton *myButton;
myButton.alpha = 0.4;
myButton.enabled = NO;
So your UIButton looks like unusable ;)
Simply make a UIButton category like the following and import #import "UIButton+StateColors.h" in the classes where you want to use it.
.h
#import <UIKit/UIKit.h>
#interface UIButton (StateColors)
-(void)makeDisabled:(BOOL)flag;
#end
.m
#import "UIButton+StateColors.h"
#define ENABLED_BUTTON_ALPHA 1
#define DISABLED_BUTTON_ALPHA 0.3
#implementation UIButton (StateColors)
-(void)makeDisabled:(BOOL)flag {
self.enabled = !flag;
self.alpha = flag ? DISABLED_BUTTON_ALPHA : ENABLED_BUTTON_ALPHA;
}
#end
And use it like this...
[self.emailBtn makeDisabled:NO];
[self.printBtn makeDisabled:YES];
It's a universal solution I hope...
I happened upon this question and Apple has published a new UIKit User Interface Catalog for working with Buttons in iOS 7.
In response to your question, the UIButton Class now exposes a property called adjustsImageWhenDisabled, which is "a Boolean value that determines whether the image changes when the button is disabled."
If this adjustsImageWhenDisabled property is set to "YES, the image is drawn darker when the button is disabled. The default value is YES."
I face the same problem because I had set background color.
I removed the background color and set it for UIControlStateNormal only and the default behaviour for enable/disable started to appear.
If you are setting background color instead of image try this category for converting UIColor to UIImage:
copied from here:
+ (UIImage *)imageWithColor:(UIColor *)color
{
CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
then use this:
[self.loginButton setBackgroundImage:[UIImage imageWithColor:greenColor] forState:UIControlStateNormal];
self.loginButton.enabled = NO;
to set the color as background. Now when you enable/disable, the gray effect should appear.

Changing color of small portion of UIView?

I have a UIView whose color is black and opacity is 0.9 or something like that. What I want to do is to fill the UIView with black portion, but a specified rectangular area should not get black. i.e. that particular rectangular area remains with clear color...
Any kind of help will be appreciated.
regards,
Imran
You can subclass UIView and override - (void)drawRect:(CGRect)rect
And do something of the following (untested, but used something similar myself);
- (void)drawRect:(CGRect)rect {
// fill the whole UIView with a color
[[UIColor colorWithRed:1 green:1 blue:1 0.9] setFill];
UIRectFill( rect );
// draw a rect
CGRect rectIntersection = CGRectIntersection(theRectIWantToDrawIn, rect);
[[UIColor clearColor] setFill];
UIRectFill( rectIntersection );
}
The code above draws a black view with a simulated clearColor hole in it at a certain position. You could, of course, alter this behavior to your liking.
This is quite fast.
UPDATE: Do note that I set the UIView on which I want to draw the rect to UIClear color (I added it to a xib and set those properties there) and unchecked 'Opaque'. That should make the hole see-through.
UPDATE 2: My answer was based on this answer (credit where credit is due): iPhone - Draw transparent rectangle on UIView to reveal view beneath
Add another view (subview) to that area. And set its to your desired color. Thats the easy solution with your current requirements.
Or you can use some quartz core functions.
You can create a small UIView in the main view by custom and set background clear color
UIView *View1 = [[UIView alloc] initWithFrame:CGRectMake(128.0f, 50.0f, 34.0f, 34.0f)];
[View1 setBackgroundColor:[UIColor clearColor]];
[self.view addSubview:View1];
[View1 release];

How to replicate the back button?

I understand that the only way to change the color of the text of the back button is to make your own custom button:
self.navigationItem.backBarButtonItem = yourCustomBackButton;
My question is: How do I create a back button that takes tint color into account and looks exactly the same as the default back button except for the color of the text (unless it's white)?
Add a category to the UINavigationBar and set it's background color there. This code also shows how to use an image.
#implementation UINavigationBar (UINavigationBarCategory)
- (void)drawRect:(CGRect)rect {
/***
// use a custom color
UIColor *color = [UIColor colorWithRed:.455 green:.365 blue:0 alpha:.9];
3 CGContextRef context = UIGraphicsGetCurrentContext();
4 CGContextSetFillColor(context, CGColorGetComponents( [color CGColor]));
5 CGContextFillRect(context, rect);
6 self.tintColor = color;
***/
// use a custom background image
UIImage *img = [UIImage imageNamed: [PlistVariables sharedInstance].navbarBackgroundImageName ];
[img drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
self.tintColor = [PlistVariables sharedInstance].navbarTintColor;
}
Here's some sample output using RGB 192,93,0 for background brown:
It's really not possible to change the text color of the back button. You can however assign a custom view to the leftBarButtonItem property. I've put together a simple little project showing how to do that that recreates the in/out animation of the standard iOS UI. Takes a bit of hacking, but you should be able to assign a button with a label in it to the custom view and update that.
https://github.com/typeoneerror/BBCustomBackButtonViewController

White Text in UITextField = Invisible text in iPhone copy/paste select. Fix?

If I have white text in my UITextField, the selection window (when selecting text) is invisible because the background on the little window is also white.
Any way to fix this?
Sure! The background color of the loupe always matches the backgroundColor property of the text field. (But not the background property.) Example:
textField.textColor = [UIColor whiteColor];
textField.backgroundColor = [UIColor blackColor];
If your text field absolutely requires a transparent background, you'll have to fake it—by using a background image containing the graphics underneath the text field. You may do it manually—by taking a screenshot of your interface and cropping it—or programmatically, like this:
#import <QuartzCore/CALayer.h>
...
// `view` contains the graphics underneath the text field
UIGraphicsBeginImageContext(textField.bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGPoint origin = [textField convertPoint:textField.bounds.origin toView:view];
CGContextTranslateCTM(context, -origin.x, -origin.y);
[view.layer renderInContext:context];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
textField.background = image;
Since the background is drawn on top of the background color, the text field will appear transparent, and you'll be able to use any background color you want for the loupe.
I'm afraid not. The problem's existed since the earliest days of the iPhone OS—white text appears as white-on-white in the cursor-positioning loupe as well. If this is a serious problem for your app, your only real options are to change the text color or to file a radar feature request with Apple.
Glass takes color from textView.backgroundColor. So I made some dirty hack that works great:
#interface FakeBgTextView : UITextView {
UIColor *_fakeBackgroundColor;
}
- (UIColor *)backgroundColor;
- (void)setFakeBackgroundColor:(UIColor *)color;
#end
#implementation FakeBgTextView
...
- (UIColor *)backgroundColor {
return _fakeBackgroundColor;
}
- (void)setFakeBackgroundColor:(UIColor *)color {
[_fakeBackgroundColor release];
_fakeBackgroundColor = [color retain];
}
...
#end
I know this is a little old, but in iOS5, it appears to be a simulator-only issue. It will render correctly on the device.
One solution that I've employed for this issue is to change the text color to a that will show up in the loupe (but may not look as good in the overall view) while editing and then changing it back to the better display color when finished editing.
It behaves as if you were highlighting the text of the field from a visual standpoint and allows you to use your preferred color for the display of the entered data when not editing.
Set the color to a highlight color that will have enough contrast in the loupe on didBeginEditing, then change it back on didEndEditing.
Just one other possible approach and one I've used in a couple of apps.
eg.
- (void)textFieldDidBeginEditing:(UITextField *)textField {
textField.textColor = [UIColor colorWithRed:116.0/255.0 green:160.0/255.0 blue:246.0/255.0 alpha:1.0];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
textField.textColor = [UIColor colorWithRed:224.0/255.0 green:224.0/255.0 blue:224.0/255.0 alpha:1.0];
}

iPhone development: How to create colored or translucent background for UIActionSheet?

When you try deleting a note in iPhone's Notes application, an UIActionSheet pops up. The sheet is translucent (but not black translucent). How is that achieved? Is it possible to make the background of UIActionSheet a certain color?
I usually implement the following delegate method:
- (void)willPresentActionSheet:(UIActionSheet *)actionSheet
Just to make a sample. In this case I use a stretched png as a background:
- (void)willPresentActionSheet:(UIActionSheet *)actionSheet {
UIImage *theImage = [UIImage imageNamed:#"detail_menu_bg.png"];
theImage = [theImage stretchableImageWithLeftCapWidth:32 topCapHeight:32];
CGSize theSize = actionSheet.frame.size;
// draw the background image and replace layer content
UIGraphicsBeginImageContext(theSize);
[theImage drawInRect:CGRectMake(0, 0, theSize.width, theSize.height)];
theImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[[actionSheet layer] setContents:(id)theImage.CGImage];
}
and this is the result:
alt text http://grab.by/4yF1
You can use the code below:
actionSheetObj.actionSheetStyle=UIActionSheetStyleBlackOpaque;
or
actionSheetObj.actionSheetStyle=UIActionSheetStyleBlackTranslucent;
actionSheetObj.actionSheetStyle=UIActionSheetStyleBlackTranslucent;
It's not too difficult. You can use the following code:
CGSize mySize = myActionSheet.bounds.size;
CGRect myRect = CGRectMake(0, 0, mySize.width, mySize.height);
UIImageView *redView = [[[UIImageView alloc] initWithFrame:myRect] autorelease];
[redView setBackgroundColor:[UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:0.5]];
[myActionSheet insertSubview:redView atIndex:0];
Just make sure you present the UIActionSheet before doing this or the size wont be set. That makes it kind of ugly, but you could do something like:
[myActionSheet showInView:self.view];
if (!redAdded) {
redAdded = YES;
//THE ABOVE CODE GOES HERE
}
You can definitely adjust the opacity by setting the alpha value. Interface Builder lets you edit the value directly, but in code I think you would do:
[[myActionSheet view] setOpaque:NO];
[[myActionSheet view] setAlpha:0.5];
I'm not sure if you need the setOpaque call or not - I think that is used to help optimize performance, as the iPhone won't try to render anything hidden by the opaque view.
It looks black to me (note: using 2.2.1). The only reason there's a color to it is because of the yellow behind it.
One option would be to use the black transparent background and find out the size and speed of the action sheet. Then create a view and animate it in at the same time you show the action sheet, just underneath it, to give it a tint different than the color naturally behind the action sheet. You would have to make the color view also translucent so you could see behind that as well.
I'm not sure if you can, but you might also try adjusting the opacity of the action sheet itself as well.