如何在iOS7中正确定位后退按钮

时间:2014-03-31 17:35:41

标签: objective-c ios7 uinavigationbar uinavigationitem

我使用此代码将自定义图像用作整个应用程序中的后退按钮。

[[UINavigationBar appearance] setBackIndicatorImage:[UIImage imageNamed:@"back"]];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"back"]];

图像尺寸为30 x 30。

代码将图像添加为后退按钮,但位置不正确,如下图所示:

back button not correct positioned

关于如何在不修改尺寸的情况下正确定位图像的任何想法(至少是图像的可视部分(圆圈+箭头))?

编辑:

我不想使用自定义后退按钮,因为这会强制我禁用iOS7中的滑动/后退手势

7 个答案:

答案 0 :(得分:21)

修改
我想我可能已经找到了这个技巧(在iOS 7设计资源中 - UIKit用户界面目录。)
栏按钮项

  

请注意,除非您将其渲染模式明确设置为UIImageRenderingModeAlwaysOriginal,否则条形图按钮图像将自动呈现为导航栏中的模板图像。有关更多信息,请参阅模板图像。

模板图片下,他们有一些代码来指定UIImageRenderingMode。

UIImage *myImage = [UIImage imageNamed:@"back"];
UIImage *backButtonImage = [myImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];  
// now use the new backButtomImage
[[UINavigationBar appearance] setBackIndicatorImage:backButtonImage];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:backButtonImage];

尝试使用对齐插图创建UIImage,然后设置Back Indicator图像。

UIEdgeInsets insets = UIEdgeInsetsMake(10, 0, 0, 0); // or (0, 0, -10.0, 0)
UIImage *alignedImage = [[UIImage imageNamed:@"back"] imageWithAlignmentRectInsets:insets];  
[[UINavigationBar appearance] setBackIndicatorImage:alignedImage];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:alignedImage];

您也可以尝试调整UINavigationBar标题文本的位置

[[UINavigationBar appearance] setTitleVerticalPositionAdjustment:(CGFloat)adjustment forBarMetrics:(UIBarMetrics)barMetrics];

答案 1 :(得分:8)

好吧,只需按照其中一条建议修复布局并丢失iOS 7“后退手势”,然后使用UIScreenEdgePanGestureRecognizer进行修复!

  

UIScreenEdgePanGestureRecognizer查找从屏幕边缘附近开始的平移(拖动)手势。在某些情况下,系统使用屏幕边缘手势来启动视图控制器转换。您可以使用此类为您自己的操作复制相同的手势行为。

答案 2 :(得分:6)

请看下面的编辑!!!

我不久前在iOS7中创建了一个自定义后退按钮。我的箭头上有一个箭头。我认为pawan的建议是一个好的开始。要使用您可以使用的自定义图像创建后退按钮,

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStylePlain target:self action:@selector(backButtonClicked)];
[backButton setBackgroundImage:finalImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[backButton setTitlePositionAdjustment:UIOffsetMake(-20, 0) forBarMetrics:UIBarMetricsDefault];

self.navigationItem.leftBarButtonItem = backButton;

我的图像finalImage是两个不同图像的合成,但您可以使用“后”图像。但我认为这就是问题所在。我的图像是复合图像,您可能也想制作复合图像,但在背面图标上方留出一个清晰的空间。我在我的图标右侧放置了一个清晰的空间来调整它的间距。这是代码,

UIImage *arrow = [UIImage imageNamed:@"back.png"];
UIImage *wordSpace = [UIImage imageNamed:@"whiteSpace.png"];
CGSize size = CGSizeMake(arrow.size.width + wordSpace.size.width, arrow.size.height);
UIGraphicsBeginImageContext(size);
[arrow drawInRect:CGRectMake(0, 0, arrow.size.width, size.height)];
[wordSpace drawInRect:CGRectMake(arrow.size.width, 0, wordSpace.size.width, wordSpace.size.height)];
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext(); 

图像wordSpace是我在photoshop中制作的一个清晰的png,所以我的新后退按钮图像没有被拉伸。您可能希望在顶部放置一个清晰的png,将图标向下推一点。在photoshop中制作它的大小。你认为调整应该是什么。您可能需要对此进行一些改进。并确保更改CGSize以使其适合您的图标和空白区域。

我的话回来了,所以我看了

[backButton setTitlePositionAdjustment:UIOffsetMake(-20, 0) forBarMetrics:UIBarMetricsDefault];

我不得不玩一下这条线以使它看起来尽可能好但它终于给了我想要的-20。我甚至调整了我的第二个变量0,这移动了实际的图标。 -5把图标放到远处,但它的另一个选项是清晰的png。

现在要处理你希望它成为一个真正的后退按钮的事实。看看我发布的第一行代码。按钮上的操作是@selector(backButtonClicked)。所以你需要做的就是制作这种方法,你应该好好去!

- (void)backButtonClicked
{
  NSLog(@"going back");
  [self.navigationController popViewControllerAnimated:YES];
}

希望这有点帮助。

enter image description here

EDIT *****

我正在玩我的代码一点点,找到了一个更好的方法来移动后面的图标。我只是使用了一个轮子,因为我没有你做过的那个,但它的工作方式是一样的。

由于您不想要标题,您可以使用此代码创建按钮

UIImage *image = [UIImage imageNamed:@"781-ships-wheel.png"];

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStylePlain target:self action:@selector(backButtonClicked)];

只需使用图标名称更改781内容即可。然后你可以使用以下内容移动它,

[backButton setImageInsets:UIEdgeInsetsMake(20, 0, -20, 0)];

看看这张照片。

pic one

这显示了相当大的图标,但我想向您展示这个想法。 Edge插入的数字是Top,Left,Bottom和Right。如果您不需要以这种方式移动,请不要左右触摸,更改顶部和底部。但请注意,如果你需要像我一样将它向下移动20点,(太多了)你需要在底部偏移负面,否则图标将被压缩。这就是所有零的看法。

pic with zeros

所以你几乎可以随心所欲地移动它,但你仍然需要设置@selector(backButtonClicked)使其像真正的后退按钮一样工作。

答案 3 :(得分:5)

这是 Swift 2 版本。 最简单的方法是这样的。将此代码放在AppDelegate

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        let navigationBarAppearace = UINavigationBar.appearance()
        let image = UIImage(named: "back-btn")
        navigationBarAppearace.backIndicatorImage = image
        navigationBarAppearace.backIndicatorTransitionMaskImage = image

        return true
    }
  

如果你的后退按钮有背景颜色,它可能无法正常工作。

为每个分辨率添加您的图标asset folder,如下所示: enter image description here

答案 4 :(得分:3)

你可以试试这个

self.navigationItem.leftBarButtonItem.imageInsets = UIEdgeInsetsMake(0, 0, 10, 0);

答案 5 :(得分:3)

问题是你的图像太高了。为了证明这一点,首先尝试这段代码:

UIGraphicsBeginImageContextWithOptions(CGSizeMake(10,20), NO, 0);
CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(6,0,4,20));
UIImage* im = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.navbar.backIndicatorImage = im;
UIGraphicsBeginImageContextWithOptions(CGSizeMake(10,20), NO, 0);
UIImage* im2 = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.navbar.backIndicatorTransitionMaskImage = im2;

看起来很好。现在,在20次调用中将30更改为CGSizeMake

UIGraphicsBeginImageContextWithOptions(CGSizeMake(10,30), NO, 0);
CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(6,0,4,20));
UIImage* im = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.navbar.backIndicatorImage = im;
UIGraphicsBeginImageContextWithOptions(CGSizeMake(10,30), NO, 0);
UIImage* im2 = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.navbar.backIndicatorTransitionMaskImage = im2;

图标现在太高了。

所以只需要让你的图像高20像素,一切都会很好。

答案 6 :(得分:1)

UIEdgeInsets insets = UIEdgeInsetsMake(0, 0, -2, 0); // or (2,0,0,0)
UIImage *backArrowImage = [[UIImage imageNamed:@"back"] imageWithAlignmentRectInsets:insets];

[[UINavigationBar appearance] setBackIndicatorImage:backArrowImage];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:backArrowImage];