2

我正在使用 iOS 5 UIAppearance 协议来使用自定义导航栏后退按钮,如此处所示。与我发现的其他方法不同,这是最好的方法,因为它保留了默认的后退按钮动画和行为。

唯一的问题是我无法更改其大小或将其设置为not clip subviews。这是正在发生的事情:

剪切图像

A 是预期行为,B 是默认样式,C 是剪裁结果。

不幸的是,这并不像将 UIBarButtonItem 设置为 clipsToBounds=NO 那样简单。

有谁知道如何解决这个问题?谢谢!

4

2 回答 2

5

正如您所发现的,UIAppearance代理不会让您调整按钮本身的尺寸:UIBarButtonItem文档中给出了支持的外观方法列表,虽然它包括标题标签本身的指标,但按钮是禁止使用的。

值得一提的是,就可触摸区域而言,按钮本身实际上是 44 pts(88 像素,如果你在视网膜中)高,只是按钮图形比这小。

如果您对 3 pt 的高度差不以为然,那么最好的选择可能是创建自己的自定义按钮并使用该UINavigationItem setLeftBarButtonItem方法。正如您所指出的,您将需要实现一个附加到该按钮的简短方法,popNavigationController以确保保持正确的行为。

更新:我刚刚发现,如果您将后退按钮保持在身边,实际上,可以对其进行动画处理,使其以与标准后退按钮类似的方式滑动。在下面的代码中self.backButtonUIButton您将在您的initWithCustomView UIBarButtonItem方法中使用的。

- (void)viewWillDisappear:(BOOL)animated {
    [UIView animateWithDuration:0.3 
                     animations:^{
                         self.backButton.frame = CGRectMake(self.backButton.frame.origin.x+100, 
                                                            self.backButton.frame.origin.y, 
                                                            self.backButton.frame.size.width, 
                                                            self.backButton.frame.size.height);
                     }];
}

...这将在视图控制器消失时触发(即,当弹出推送时),但您可以挂钩到UINavigationController委托以仅在弹出导航控制器时触发它。按下控制器时,它似乎肯定会移动按钮,尽管我只在模拟器上测试过它。

于 2012-05-06T15:07:15.643 回答
2

我最终为我在导航控制器中使用的每个 VC 使用了一个自定义视图控制器类。

OEViewController.h

#import <UIKit/UIKit.h>
#import "OEBarButtonItem.h"

@interface OEViewController : UIViewController

@property (nonatomic, retain) UIButton *backButton;
@property (atomic) BOOL pushed;

- (void)pushViewController:(UIViewController*)vc;

@end

OEViewController.m

#import "OEViewController.h"

#define ANIMATION_DURATION 0.33

@implementation OEViewController
@synthesize backButton, pushed;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    pushed=YES;
    self.navigationItem.hidesBackButton = YES;

    backButton = [OEBarButtonItem backButtonWithTitle:[(UIViewController*)[self.navigationController.viewControllers objectAtIndex:[self.navigationController.viewControllers count]-2] title]];

    [backButton addTarget:self action:@selector(backButtonPressed:) forControlEvents:UIControlEventTouchUpInside];

    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    if (pushed) {
        self.backButton.frame = CGRectMake(self.backButton.frame.origin.x+100, 
                                           self.backButton.frame.origin.y+6, 
                                           self.backButton.frame.size.width, 
                                           self.backButton.frame.size.height);
        [UIView animateWithDuration:ANIMATION_DURATION 
                         animations:^{
                             self.backButton.frame = CGRectMake(self.backButton.frame.origin.x-100, 
                                                                self.backButton.frame.origin.y, 
                                                                self.backButton.frame.size.width, 
                                                                self.backButton.frame.size.height);
                         }];
        pushed=NO;
    } else {
        self.backButton.frame = CGRectMake(self.backButton.frame.origin.x-100, 
                                           self.backButton.frame.origin.y, 
                                           self.backButton.frame.size.width, 
                                           self.backButton.frame.size.height);
        [UIView animateWithDuration:ANIMATION_DURATION 
                         animations:^{
                             self.backButton.frame = CGRectMake(self.backButton.frame.origin.x+100, 
                                                                self.backButton.frame.origin.y, 
                                                                self.backButton.frame.size.width, 
                                                                self.backButton.frame.size.height);
                         }];
    }
}

- (void)backButtonPressed:(id)sender {
    [self.navigationController popViewControllerAnimated:YES];
    [UIView animateWithDuration:ANIMATION_DURATION 
                     animations:^{
                         self.backButton.frame = CGRectMake(self.backButton.frame.origin.x+100, 
                                                            self.backButton.frame.origin.y, 
                                                            self.backButton.frame.size.width, 
                                                            self.backButton.frame.size.height);
                     }];
}

- (void)pushViewController:(UIViewController*)vc {
    [self.navigationController pushViewController:vc animated:YES];
    [UIView animateWithDuration:ANIMATION_DURATION 
                     animations:^{
                         self.backButton.frame = CGRectMake(self.backButton.frame.origin.x-100, 
                                                            self.backButton.frame.origin.y, 
                                                            self.backButton.frame.size.width, 
                                                            self.backButton.frame.size.height);
                     }];
}

@end

与使用 UIAppearance 相比,这具有使用 iOS 4.0+ 的额外好处。

感谢@lxt 的帮助!

于 2012-05-08T02:34:09.820 回答