如何在iOS7中正确定位后退按钮
Posted
技术标签:
【中文标题】如何在iOS7中正确定位后退按钮【英文标题】:How to properly position the back button in iOS7 【发布时间】:2014-03-31 17:35:40 【问题描述】:我使用此代码在整个应用程序中使用自定义图像作为后退按钮。
[[UINavigationBar appearance] setBackIndicatorImage:[UIImage imageNamed:@"back"]];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"back"]];
图像尺寸为 30 x 30。
代码将图像添加为后退按钮,但位置不正确,如下图所示:
关于如何在不修改其尺寸(至少是图像的视觉部分(圆圈+箭头))的情况下正确定位图像的任何想法?
编辑:
我不想使用自定义后退按钮,因为这会迫使我在 iOS7 中禁用滑动/返回手势
【问题讨论】:
你应该考虑 "UIImage *backButton = [[UIImage imageNamed:@"blueButton"] resizableImageWithCapInsets:UIEdgeInsetsMake(12, 12, 12, 12)];"然后将此图像设置为后退按钮。 如果我这样做,“ios7-back-gesture”就不起作用 您在此处提供的插图“UIEdgeInsetsMake(12, 12, 12, 12)”。您需要根据您的要求进行更改。关注这个reference link 我不明白这如何解决问题,因为后退按钮不是 UINavigationBar 的背景,我不需要以任何方式/模式重复它 因为我不想从头开始一个项目。但话又说回来,我不需要帮助。 【参考方案1】:编辑 我想我可能已经找到了诀窍(在 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];
【讨论】:
这会将箭头(图像)留在同一个地方,对我不起作用 查看我的编辑——来自 Apple 的 UIKit 界面目录。 “如果您在图像上设置了 UIImageRenderingModeAutomatic,它将根据其上下文被视为模板或原始图像。”这是任何 UIIImage 的默认设置。您的自定义后退按钮可能被视为模板或模板图像(希望将其视为原始图像将在 UINavigationBar 中正确呈现。) 好吧,如果有答案,它可能就在document 的某个地方。只是为了好玩,您是否尝试过从模拟器/设备中删除应用并进行清理/重建? 我得到了它的工作,与前两段代码的混搭仅供参考 第二个选项对我有用(带有插图的图像)。我也必须使用 -10 底部的插图。谢谢!【参考方案2】:好吧,只需按照其中一个建议来修复布局并丢失 iOS 7“后退手势”,然后使用 UIScreenEdgePanGestureRecognizer
修复它!
UIScreenEdgePanGestureRecognizer 查找从屏幕边缘附近开始的平移(拖动)手势。系统在某些情况下使用屏幕边缘手势来启动视图控制器转换。您可以使用此类为您自己的操作复制相同的手势行为。
【讨论】:
【参考方案3】:请看下面的编辑!!!
不久前,我在 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();
Image wordSpace 是我在 Photoshop 中制作的清晰 png,因此我的新后退按钮图像没有被拉伸。您可能希望在顶部放置一个清晰的 png,以将图标向下推一点。在 Photoshop 中将它的 size.height 设置为您认为应该进行的调整。您可能需要对此有所了解。并确保更改 CGSize 以使其适合您的图标和空白空间。
我的回话有点不对劲,所以我看了看
[backButton setTitlePositionAdjustment:UIOffsetMake(-20, 0) forBarMetrics:UIBarMetricsDefault];
我不得不稍微调整一下这条线以使其看起来尽可能好,但它最终给了我想要的 -20。我什至调整了我的第二个变量 0,这移动了实际的图标。 -5 将图标放得很远,但它是清除 png 的另一个选项。
现在处理您希望它成为实际后退按钮的事实。看看我发布的第一行代码。按钮上的操作是@selector(backButtonClicked)。所以你需要做的就是做那个方法,你应该很高兴!
- (void)backButtonClicked
NSLog(@"going back");
[self.navigationController popViewControllerAnimated:YES];
希望这会有所帮助。
编辑*****
我正在玩弄我的代码,并找到了一种更好的方法来移动后退图标。我只是用了一个***,因为我没有和你一样的***,但它的工作原理是一样的。
由于您并不真正想要标题,因此您可以使用此代码创建按钮,
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)];
看看这张照片。
这会使图标显着下降,但我想向您展示这个想法。边缘插图的数字是顶部、左侧、底部和右侧。如果你不需要那样移动它,不要触摸左右,改变顶部和底部。但是请注意,如果您需要像我一样将其向下移动 20 点,(太多)您需要在底部偏移负数,否则图标将被压缩。这就是全零时的样子。
所以你几乎可以将它移动到任何你想要的地方,但你仍然需要设置 @selector(backButtonClicked) 让它像真正的后退按钮一样工作。
【讨论】:
嗨@Douglas,如果我愿意在iOS7中禁用后退手势(我不是),你的回答会起作用。这就是问题所在! 我不明白,这仍然允许后退手势。您只是用自己的图标替换通用的后退箭头和单词。但这样做会将新图标的动作转换为后退手势。 所以你想要后退手势(滑动返回)和后退按钮(点击返回)? @Bernat,带箭头的圆圈不是 iOS7 上默认的后退按钮。你自己加的吗?如果是这样,那么您现在需要做的就是将 UISwipeGestureRecognizer 连同我在编辑中的代码放在一起,您将拥有两者。你试过滑动吗? UISwipeGestureRecognizer *swipeMe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeLeft)]; swipeMe.direction = UISwipeGestureRecognizerDirectionLeft; [self.view addGestureRecognizer:swipeMe];然后在方法 swipeLeft 中执行相同的 popViewControllerAnimated:YES。 我现在将使用你的“解决方案”,但我无法检查你的答案是否正确,因为我仍然有后退手势的问题。【参考方案4】:这是 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
,如下所示:
【讨论】:
【参考方案5】:你可以试试这个
self.navigationItem.leftBarButtonItem.imageInsets = UIEdgeInsetsMake(0, 0, 10, 0);
【讨论】:
这会将箭头(图像)留在同一个地方,对我不起作用【参考方案6】:问题是您的图像太高了。为了证明这一点,首先尝试以下代码:
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;
看起来不错。现在将两个CGSizeMake
调用中的20
更改为30
:
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 像素,一切都会好起来的。
【讨论】:
【参考方案7】: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];
【讨论】:
以上是关于如何在iOS7中正确定位后退按钮的主要内容,如果未能解决你的问题,请参考以下文章