iphone Back Buttons

 http://www.mlsite.net/blog/?p=1544


Today, a quick note about “back” buttons. The chevron-shaped button that appears by default in the left-hand position of a nav. bar can be a little problematic. In particular, the system-provided button doesn’t cross-fade properly with other buttons, and it can be tricky to change its text programmatically. Furthermore, there doesn’t seem to be any way to (simply) generate your own chevron-shaped buttons. To address these issues, I created a UIButton category, presented below. This category allows you to create your own chevron-shaped buttons.

Problems

Let me first quickly explain the problems we’re trying to solve. First: cross-fade. Sometimes you want to swap out the buttons on a nav. bar with a fade animation. You might use the UINavigationController's setLeftBarButtonItem:animated: method to do this. Unfortunately, this method doesn’t do a proper cross-fade when a back button is involved; the back button tends to “pop”. Using setHidesBackButton:animated: doesn’t really help, unless you’re willing to schedule two animations.

A related problem has to do with relabeling the back button. For instance, in our Demineproject, the back button is relabeled from “Pause” to “Menu” when a puzzle is completed. It’s not clear how you’d do this programmatically, since:

  • It’s not easy to get a pointer to the system-created back button
  • That button is owned by another controller’s UINavigationItem, and shared among all its “children”
  • The UIBarItem documentation states that a title should be set before a bar item is added to a nav. bar

All in all, it seems like it’s necessary to create your own chevron-shaped buttons in some cases, and it doesn’t seem like the system provides a way to do this.

Art

We’ll need some art. Here, experimentally determined, are appropriate images for the clicked and normal states of the back button.

 

 

Code

Now, the code. First, we’ll need to declare a category in a header file:

@interface UIButton (NavButton)

- (UIButton*)configureForBackButtonWithTitle:(NSString*)title target:(id)target action:(SEL)action;

@end

And then, we’ll need to define the new method in a source file:

- (UIButton*)configureForBackButtonWithTitle:(NSString*)title target:(id)target action:(SEL)action
{
	// Experimentally determined
	CGFloat padTRL[3] = {6, 8, 12};

	// Text must be put in its own UIView, s.t. it can be positioned to mimic system buttons
	UILabel* label = [[UILabel alloc] init];
	label.backgroundColor = [UIColor clearColor];
	label.font = [UIFont boldSystemFontOfSize:12];
	label.textColor = [UIColor whiteColor];
	label.shadowColor = [UIColor darkGrayColor];
	label.shadowOffset = CGSizeMake(0, -1);
	label.text = title;
	[label sizeToFit];

	// The underlying art files must be added to the project
	UIImage* norm = [[UIImage imageNamed:@"back_norm.png"] stretchableImageWithLeftCapWidth:13 topCapHeight:0];
	UIImage* click = [[UIImage imageNamed:@"back_click.png"] stretchableImageWithLeftCapWidth:13 topCapHeight:0];
	[self setBackgroundImage:norm forState:UIControlStateNormal];
	[self setBackgroundImage:click forState:UIControlStateHighlighted];
	[self addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];

	// Calculate dimensions
	CGSize labelSize = label.frame.size;
	CGFloat controlWidth = labelSize.width+padTRL[1]+padTRL[2];
	controlWidth = controlWidth>=norm.size.width?controlWidth:norm.size.width;

	// Assemble and size the views
	self.frame = CGRectMake(0, 0, controlWidth, 30);
	[self addSubview:label];
	label.frame = CGRectMake(padTRL[2], padTRL[0], labelSize.width, labelSize.height);

	// Clean up
	[label release];
	return self;
}

Invocation

To create a new button with this code, you might write something like this:

[[UIBarButtonItem alloc] initWithCustomView:[[UIButton buttonWithType:UIButtonTypeCustom] configureForBackButtonWithTitle:@"Menu" target:self action:@selector(dismiss)]];

Caveats

There might be an easier way to do this, but I can’t see it right now. This approach does represent a bit of a hack; if AAPL changes the appearance of navigation bars/back buttons in future releases of iPhone OS, the buttons produced by this method won’t look right. (I guess you’d need new code/art that matches the new system look and, at least transitionally, introspective code that figures out the system version and invokes the appropriate code with the appropriate art.) Ah well. Life: Still imperfect.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值