在 UIToolbar 上创建左箭头按钮(如 UINavigationBar 的“后退”样式)

发布于 2024-07-07 22:20:22 字数 593 浏览 7 评论 0原文

我想在 UIToolbar 中创建一个“后退”左箭头边框按钮。

据我所知,获得其中之一的唯一方法是将 UINavigationController 保留为默认设置,并且它对左栏项目使用一个。 但我无法将其创建为 UIBarButtonItem,因此我无法在标准 UIToolbar 中创建一个,即使它们与 非常相似>UINavigationBar

我可以使用按钮图像手动创建它,但我无法在任何地方找到源图像。 它们具有 Alpha 通道边缘,因此屏幕截图和剪切不会获得非常通用的结果。

除了对我打算使用的每种尺寸和配色方案进行屏幕截图之外,还有什么想法吗?

更新:请停止回避这个问题并建议我不应该问这个问题而应该使用UINavigationBar。 我的应用程序是 Instapaper Pro。 它只显示一个底部工具栏(以节省空间并最大化可读内容区域),我希望在底部放置一个左箭头形状的后退按钮。

告诉我不需要这样做不是答案,而且当然不值得赏金。

I'd love to create a "back" left-arrow-bezel button in a UIToolbar.

As far as I can tell, the only way to get one of these is to leave UINavigationController at default settings and it uses one for the left bar item. But there's no way I can find to create one as a UIBarButtonItem, so I can't make one in a standard UIToolbar, even though they're very similar to UINavigationBars.

I could manually create it with button images, but I can't find the source images anywhere. They have alpha-channel edges, so screenshotting and cutting won't get very versatile results.

Any ideas beyond screenshotting for every size and color scheme I intend to use?

Update: PLEASE STOP dodging the question and suggesting that I shouldn't be asking this and should be using UINavigationBar. My app is Instapaper Pro. It shows only a bottom toolbar (to save space and maximize readable content area), and I wish to put a left-arrow-shaped Back button in the bottom.

Telling me that I shouldn't need to do this is not an answer and certainly doesn't deserve a bounty.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(24

你在我安 2024-07-14 22:20:23

你为什么做这个? 如果您想要看起来像导航栏的东西,请使用 UINavigationBar。

工具栏具有与其相关的特定视觉样式。 iPhone 的人机界面指南指出:

工具栏出现在屏幕的底部边缘,其中包含执行与当前视图中的对象相关的操作的按钮。

然后,它给出了几个没有文本的大致方形图标的视觉示例。 我强烈建议您关注 HIG 的动态。

Why are you doing this? If you want something that looks like a navigation bar, use UINavigationBar.

Toolbars have specific visual style associated with them. The Human Interface Guidelines for the iPhone state:

A toolbar appears at the bottom edge of the screen and contains buttons that perform actions related to objects in the current view.

It then gives several visual examples of roughly square icons with no text. I would urge you to follow the HIG on this.

§普罗旺斯的薰衣草 2024-07-14 22:20:22

我使用了从 http://www.teehanlax.com/blog/?p=447" 导出的以下 psd p=447

http://www.chrisandtennille.com/pictures/backbutton.psd< /a>

然后,我创建了一个自定义 UIView,在工具栏项的 customView 属性中使用它。

对我来说效果很好。


编辑: 正如PrairieHippo所指出的,maralbjo发现使用以下简单的代码就可以达到目的(需要捆绑中的自定义图像)应该是结合这个答案。 所以这里是额外的代码:

// Creates a back button instead of default behaviour (displaying title of previous screen)
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"back_arrow.png"]
                                                               style:UIBarButtonItemStyleBordered
                                                              target:self
                                                              action:@selector(backAction)];

tipsDetailViewController.navigationItem.leftBarButtonItem = backButton;
[backButton release];

I used the following psd that I derived from http://www.teehanlax.com/blog/?p=447

http://www.chrisandtennille.com/pictures/backbutton.psd

I then just created a custom UIView that I use in the customView property of the toolbar item.

Works well for me.


Edit: As pointed out by PrairieHippo, maralbjo found that using the following, simple code did the trick (requires custom image in bundle) should be combined with this answer. So here is additional code:

// Creates a back button instead of default behaviour (displaying title of previous screen)
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"back_arrow.png"]
                                                               style:UIBarButtonItemStyleBordered
                                                              target:self
                                                              action:@selector(backAction)];

tipsDetailViewController.navigationItem.leftBarButtonItem = backButton;
[backButton release];
北城挽邺 2024-07-14 22:20:22

Unicode 方法

我认为仅使用 unicode 字符来完成工作要容易得多。 您可以通过谷歌搜索 Unicode 三角形 或 < a href="http://www.fileformat.info/info/unicode/block/arrows/list.htm" rel="nofollow noreferrer">Unicode 箭头。 从iOS6开始,苹果将字符更改为带有边框的表情符号字符。 要禁用边框,我添加了 0xFE0E Unicode 变体选择器

NSString *backArrowString = @"\U000025C0\U0000FE0E"; //BLACK LEFT-POINTING TRIANGLE PLUS VARIATION SELECTOR

UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:backArrowString style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.leftButtonItem = backBarButtonItem;

该代码块仅用于演示。 它适用于任何接受 NSString 的按钮。

有关字符的完整列表,请在 Google 中搜索 Unicode 字符和您想要的内容。 这是黑色左指三角形的条目。

结果

结果

The Unicode Method

I think it is much easier to just use a unicode character to get the job done. You can look through arrows by googling either Unicode Triangles or Unicode Arrows. Starting with iOS6 Apple changed the character to be an emoji character with a border. To disable the border I add the 0xFE0E Unicode Variation Selector.

NSString *backArrowString = @"\U000025C0\U0000FE0E"; //BLACK LEFT-POINTING TRIANGLE PLUS VARIATION SELECTOR

UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:backArrowString style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.leftButtonItem = backBarButtonItem;

The code block is just for the demo. It would work in any button that accepts an NSString.

For a full list of characters search Google for Unicode character and what you want. Here is the entry for Black Left-Pointing Triangle.

Result

The result

糖粟与秋泊 2024-07-14 22:20:22

警告:有报告称这不适用于 iOS 6。这可能仅适用于旧版本的操作系统。 显然,至少有一个开发人员的应用程序因使用此技巧而被拒绝(请参阅评论)。 使用风险自负。 使用图像(参见上面的答案)可能是一个更安全的解决方案。

无需使用 sekr1t 按钮类型 101 添加您自己的图像文件即可完成此操作以获得正确的形状。 对我来说,诀窍是弄清楚我可以使用 initWithCustomView 来创建 BarButtonItem。 我个人需要动态导航栏而不是工具栏,但我用工具栏测试了它,代码几乎相同:

// create button
UIButton* backButton = [UIButton buttonWithType:101]; // left-pointing shape!
[backButton addTarget:self action:@selector(backAction) forControlEvents:UIControlEventTouchUpInside];
[backButton setTitle:@"Back" forState:UIControlStateNormal];

// create button item -- possible because UIButton subclasses UIView!
UIBarButtonItem* backItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];

// add to toolbar, or to a navbar (you should only have one of these!)
[toolbar setItems:[NSArray arrayWithObject:backItem]];
navItem.leftBarButtonItem = backItem;

如果您在工具栏上执行此操作,则必须进行调整如何设置这些项目,但这取决于代码的其余部分,我将其作为练习留给读者。 :P 这个示例对我有用(编译并运行)。

等等,阅读 HIG,不要使用未记录的功能,等等。 只有六种受支持的按钮类型,这不是其中之一。

WARNING: There are reports that this will not work on iOS 6. This might only work on older versions of the OS. Evidently at least one dev has had their app rejected for using this trick (see the comments). Use at your own risk. Using an image (see answer above) might be a safer solution.

This can be done without adding in your own image files using sekr1t button type 101 to get the correct shape. For me the trick was figuring out that I could use initWithCustomView to create the BarButtonItem. I personally needed this for a dynamic navbar rather than a toolbar, but I tested it with a toolbar and the code is nearly the same:

// create button
UIButton* backButton = [UIButton buttonWithType:101]; // left-pointing shape!
[backButton addTarget:self action:@selector(backAction) forControlEvents:UIControlEventTouchUpInside];
[backButton setTitle:@"Back" forState:UIControlStateNormal];

// create button item -- possible because UIButton subclasses UIView!
UIBarButtonItem* backItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];

// add to toolbar, or to a navbar (you should only have one of these!)
[toolbar setItems:[NSArray arrayWithObject:backItem]];
navItem.leftBarButtonItem = backItem;

If you're doing this on a toolbar you'll have to tweak how you set the items, but that depends on the rest of your code and I leave that as an exercise for the reader. :P This sample worked for me (compiled & run).

Blah blah, read the HIG, don't use undocumented features, and all that. There's only six supported button types and this isn't one of them.

永言不败 2024-07-14 22:20:22

在此处输入图像描述

首先,您必须找到后退按钮的图像。 我使用了一个名为 Extractor 的不错的应用程序,它可以从 iPhone 中提取所有图形。
iOS7中,我设法检索名为UINavigationBarBackIndicatorDefault的图像,它是黑色的,因为我需要红色色调我使用Gimp将颜色更改为红色。< /strike>

编辑:

正如 btate 在他的评论中提到的,没有必要使用图像编辑器更改颜色。 下面的代码应该可以解决这个问题:

imageView.tint = [UIColor redColor];
imageView.image = [[UIImage imageNamed:@"UINavigationBarBackIndicatorDefault"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

然后我创建了一个视图,其中包含带有该箭头的 imageView、带有自定义文本的标签,并且在视图顶部有一个带有操作的按钮。 然后我添加了一个简单的动画(淡入淡出和平移)。

以下代码模拟后退按钮的行为(包括动画)。

-(void)viewWillAppear:(BOOL)animated{
        UIImageView *imageView=[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"UINavigationBarBackIndicatorDefault"]];
        [imageView setTintColor:[UIColor redColor]];
        UILabel *label=[[UILabel alloc] init];
        [label setTextColor:[UIColor redColor]];
        [label setText:@"Blog"];
        [label sizeToFit];

        int space=6;
        label.frame=CGRectMake(imageView.frame.origin.x+imageView.frame.size.width+space, label.frame.origin.y, label.frame.size.width, label.frame.size.height);
        UIView *view=[[UIView alloc] initWithFrame:CGRectMake(0, 0, label.frame.size.width+imageView.frame.size.width+space, imageView.frame.size.height)];

        view.bounds=CGRectMake(view.bounds.origin.x+8, view.bounds.origin.y-1, view.bounds.size.width, view.bounds.size.height);
        [view addSubview:imageView];
        [view addSubview:label];

        UIButton *button=[[UIButton alloc] initWithFrame:view.frame];
        [button addTarget:self action:@selector(handleBack:) forControlEvents:UIControlEventTouchUpInside];
        [view addSubview:button];

        [UIView animateWithDuration:0.33 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
            label.alpha = 0.0;
            CGRect orig=label.frame;
            label.frame=CGRectMake(label.frame.origin.x+25, label.frame.origin.y, label.frame.size.width, label.frame.size.height);
            label.alpha = 1.0;
            label.frame=orig;
        } completion:nil];

        UIBarButtonItem *backButton =[[UIBarButtonItem alloc] initWithCustomView:view];
}

- (void) handleBack:(id)sender{
}

编辑:

在我看来,更好的方法是使用手势识别器,而不是添加按钮。

UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleBack:)];
[view addGestureRecognizer:tap];
[view setUserInteractionEnabled:YES];

enter image description here

First of all you have to find an image of the back button. I used a nice app called Extractor that extracts all the graphics from iPhone.
In iOS7 I managed to retrieve the image called UINavigationBarBackIndicatorDefault and it was in black colour, since I needed a red tint I change the colour to red using Gimp.

EDIT:

As was mentioned by btate in his comment, there is no need to change the color with the image editor. The following code should do the trick:

imageView.tint = [UIColor redColor];
imageView.image = [[UIImage imageNamed:@"UINavigationBarBackIndicatorDefault"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

Then I created a view that contains an imageView with that arrow, a label with the custom text and on top of the view I have a button with an action. Then I added a simple animation (fading and translation).

The following code simulates the behaviour of the back button including animation.

-(void)viewWillAppear:(BOOL)animated{
        UIImageView *imageView=[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"UINavigationBarBackIndicatorDefault"]];
        [imageView setTintColor:[UIColor redColor]];
        UILabel *label=[[UILabel alloc] init];
        [label setTextColor:[UIColor redColor]];
        [label setText:@"Blog"];
        [label sizeToFit];

        int space=6;
        label.frame=CGRectMake(imageView.frame.origin.x+imageView.frame.size.width+space, label.frame.origin.y, label.frame.size.width, label.frame.size.height);
        UIView *view=[[UIView alloc] initWithFrame:CGRectMake(0, 0, label.frame.size.width+imageView.frame.size.width+space, imageView.frame.size.height)];

        view.bounds=CGRectMake(view.bounds.origin.x+8, view.bounds.origin.y-1, view.bounds.size.width, view.bounds.size.height);
        [view addSubview:imageView];
        [view addSubview:label];

        UIButton *button=[[UIButton alloc] initWithFrame:view.frame];
        [button addTarget:self action:@selector(handleBack:) forControlEvents:UIControlEventTouchUpInside];
        [view addSubview:button];

        [UIView animateWithDuration:0.33 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
            label.alpha = 0.0;
            CGRect orig=label.frame;
            label.frame=CGRectMake(label.frame.origin.x+25, label.frame.origin.y, label.frame.size.width, label.frame.size.height);
            label.alpha = 1.0;
            label.frame=orig;
        } completion:nil];

        UIBarButtonItem *backButton =[[UIBarButtonItem alloc] initWithCustomView:view];
}

- (void) handleBack:(id)sender{
}

EDIT:

Instead of adding the button, in my opinion the better approach is to use a gesture recognizer.

UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleBack:)];
[view addGestureRecognizer:tap];
[view setUserInteractionEnabled:YES];
幽梦紫曦~ 2024-07-14 22:20:22

我不确定这是否可行,但您可以尝试使用默认设置创建一个 UINavigationController 来创建按钮,在导航控制器的子视图层次结构中找到该按钮,调用 removeFromSuperview 上,销毁导航控制器,然后将按钮添加为工具栏的子视图。 您可能还需要在调用removeFromSuperview之前保留和按钮(然后在将其添加为工具栏的子视图后释放它)以避免它在此过程中被释放。

I'm not sure if this would work, but you could try creating a UINavigationController with the default settings to create the button, find the button in the navigation controller's subview hierarchy, call removeFromSuperview on it, destroy the navigation controller, and then add the button as a subview of your toolbar. You may also need to retain and the button before calling removeFromSuperview (and then release it after adding it as subview of your toolbar) to avoid it being deallocated during the process.

违心° 2024-07-14 22:20:22

要使带有箭头的 UIButton 非常接近(我不是设计师;)iOS 7 系统后退箭头:

标准:

标准系统后退箭头

Apple SD Gothic Neo

Apple SD Gothic Neo <字符

在 Xcode 中:

  • 关注 的标题值字段按钮(或任何其他带有文本内容的视图/控件)
  • 打开编辑 -> 特殊字符
  • 选择括号组并双击“<” 字符
  • 将字体更改为:Apple SD Gothic Neo、所需大小的常规(例如 20)
  • 根据需要更改颜色

参考 @staticVoidMan 的回答 iOS 7 上类似后退的箭头

To make a UIButton with an arrow pretty close (I'm not a designer ;) to the iOS 7 system back arrow:

Standard:

Standard system back arrow

Apple SD Gothic Neo

Apple SD Gothic Neo < character

In Xcode:

  • Focus on the title value field of the button (or any other view/control with text content)
  • Open Edit -> Special Characters
  • Select the Parentheses group and double click the '<' character
  • Change font to: Apple SD Gothic Neo, Regular with desired size (e.g. 20)
  • Change colour as you like

Ref @staticVoidMan's answer to Back-like arrow on iOS 7

温馨耳语 2024-07-14 22:20:22

后退箭头

如果您不想费心处理图像文件,可以使用以下代码在 UIView 子类中绘制箭头形状:

- (void)drawRect:(CGRect)rect {
    float width = rect.size.width;
    float height = rect.size.height;
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextBeginPath(context);
    CGContextMoveToPoint(context, width * 5.0/6.0, height * 0.0/10.0);
    CGContextAddLineToPoint(context, width * 0.0/6.0, height * 5.0/10.0);
    CGContextAddLineToPoint(context, width * 5.0/6.0, height * 10.0/10.0);
    CGContextAddLineToPoint(context, width * 6.0/6.0, height * 9.0/10.0);
    CGContextAddLineToPoint(context, width * 2.0/6.0, height * 5.0/10.0);
    CGContextAddLineToPoint(context, width * 6.0/6.0, height * 1.0/10.0);
    CGContextClosePath(context);

    CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
    CGContextFillPath(context);
}

其中箭头视图与宽度 6.0 和高度 10.0 成比例

back arrow

If you don't want to bother with image files, the arrow shape can be drawn in a UIView subclass with the following code:

- (void)drawRect:(CGRect)rect {
    float width = rect.size.width;
    float height = rect.size.height;
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextBeginPath(context);
    CGContextMoveToPoint(context, width * 5.0/6.0, height * 0.0/10.0);
    CGContextAddLineToPoint(context, width * 0.0/6.0, height * 5.0/10.0);
    CGContextAddLineToPoint(context, width * 5.0/6.0, height * 10.0/10.0);
    CGContextAddLineToPoint(context, width * 6.0/6.0, height * 9.0/10.0);
    CGContextAddLineToPoint(context, width * 2.0/6.0, height * 5.0/10.0);
    CGContextAddLineToPoint(context, width * 6.0/6.0, height * 1.0/10.0);
    CGContextClosePath(context);

    CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
    CGContextFillPath(context);
}

where the arrow view is proportional to a width of 6.0 and a height of 10.0

山有枢 2024-07-14 22:20:22
    self.navigationItem.leftBarButtonItem = self.navigationItem.backBarButtonItem;

对我有用。 当我有更多选项卡然后可以放在选项卡栏上时,我使用了这个,并且从“更多”推送的视图控制器覆盖了其 viewDidLoad 中的 leftBarButtonItem。

    self.navigationItem.leftBarButtonItem = self.navigationItem.backBarButtonItem;

Works for me. I used this when I had more tabs then could fit on the tab bar, and a view controller pushed from the "More" overrode the leftBarButtonItem in its viewDidLoad.

梦毁影碎の 2024-07-14 22:20:22

您可以通过从 UIKit ${SDKROOT}/System/Library/Frameworks/UIKit.framework/Other.artwork 中的 Other.artwork 中提取源图像来找到源图像。 改装社区有一些用于提取它们的工具,此处。 提取图像后,您可以编写一些代码以根据需要重新着色并将其设置为按钮图像。 无论你是否真的可以运送这样的东西(因为你正在嵌入派生的艺术品)可能有点冒险,所以也许你想和律师谈谈。

You can find the source images by extracting them from Other.artwork in UIKit ${SDKROOT}/System/Library/Frameworks/UIKit.framework/Other.artwork. The modding community has some tools for extracting them, here. Once you extract the image you can write some code to recolor it as necessary and set it as the button image. Whether or not you can actually ship such a thing (since you are embedding derived artwork) might be a little dicey, so maybe you want to talk to a lawyer.

江湖彼岸 2024-07-14 22:20:22

Three20 库有一种方法可以做到这一点:

  UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle: @"Title" style:UIBarButtonItemStylePlain 
                                                                target:self action:@selector(foo)];

  UIColor* darkBlue = RGBCOLOR(109, 132, 162);

  TTShapeStyle* style = [TTShapeStyle styleWithShape:[TTRoundedLeftArrowShape shapeWithRadius:4.5] next:
    [TTShadowStyle styleWithColor:RGBCOLOR(255,255,255) blur:1 offset:CGSizeMake(0, 1) next:
    [TTReflectiveFillStyle styleWithColor:darkBlue next:
    [TTBevelBorderStyle styleWithHighlight:[darkBlue shadow]
                                     shadow:[darkBlue multiplyHue:1 saturation:0.5 value:0.5]
                                      width:1 lightSource:270 next:
    [TTInsetStyle styleWithInset:UIEdgeInsetsMake(0, -1, 0, -1) next:
    [TTBevelBorderStyle styleWithHighlight:nil shadow:RGBACOLOR(0,0,0,0.15)
                                        width:1 lightSource:270 next:nil]]]]]];

  TTView* view = [[[TTView alloc] initWithFrame:CGRectMake(0, 0, 80, 35)] autorelease];
  view.backgroundColor = [UIColor clearColor];
  view.style = style;
  backButton.customView = view;


  self.navigationItem.leftBarButtonItem = backButton;

The Three20 library has a way to do this:

  UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle: @"Title" style:UIBarButtonItemStylePlain 
                                                                target:self action:@selector(foo)];

  UIColor* darkBlue = RGBCOLOR(109, 132, 162);

  TTShapeStyle* style = [TTShapeStyle styleWithShape:[TTRoundedLeftArrowShape shapeWithRadius:4.5] next:
    [TTShadowStyle styleWithColor:RGBCOLOR(255,255,255) blur:1 offset:CGSizeMake(0, 1) next:
    [TTReflectiveFillStyle styleWithColor:darkBlue next:
    [TTBevelBorderStyle styleWithHighlight:[darkBlue shadow]
                                     shadow:[darkBlue multiplyHue:1 saturation:0.5 value:0.5]
                                      width:1 lightSource:270 next:
    [TTInsetStyle styleWithInset:UIEdgeInsetsMake(0, -1, 0, -1) next:
    [TTBevelBorderStyle styleWithHighlight:nil shadow:RGBACOLOR(0,0,0,0.15)
                                        width:1 lightSource:270 next:nil]]]]]];

  TTView* view = [[[TTView alloc] initWithFrame:CGRectMake(0, 0, 80, 35)] autorelease];
  view.backgroundColor = [UIColor clearColor];
  view.style = style;
  backButton.customView = view;


  self.navigationItem.leftBarButtonItem = backButton;
枉心 2024-07-14 22:20:22

我发现使用以下简单的代码就可以解决问题(需要捆绑中的自定义图像):

// Creates a back button instead of default behaviour (displaying title of previous screen)
    UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"back_arrow.png"]
                                                                   style:UIBarButtonItemStyleBordered
                                                                  target:self
                                                                  action:@selector(backAction)];

    tipsDetailViewController.navigationItem.leftBarButtonItem = backButton;
    [backButton release];

I found that using the following, simple code did the trick (requires custom image in bundle):

// Creates a back button instead of default behaviour (displaying title of previous screen)
    UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"back_arrow.png"]
                                                                   style:UIBarButtonItemStyleBordered
                                                                  target:self
                                                                  action:@selector(backAction)];

    tipsDetailViewController.navigationItem.leftBarButtonItem = backButton;
    [backButton release];
孤独患者 2024-07-14 22:20:22

这是我在搜索所有这些解决方案和其他解决方案后最终所做的事情。 它使用从 UIKit 库存图像中提取的可拉伸 png。 这样您就可以将文本设置为您喜欢的任何内容

// Generate the background images
UIImage *stretchableBackButton = [[UIImage imageNamed:@"UINavigationBarDefaultBack.png"] stretchableImageWithLeftCapWidth:14 topCapHeight:0];
UIImage *stretchableBackButtonPressed = [[UIImage imageNamed:@"UINavigationBarDefaultBackPressed.png"] stretchableImageWithLeftCapWidth:13 topCapHeight:0];
// Setup the UIButton
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
[backButton setBackgroundImage:stretchableBackButton forState:UIControlStateNormal];
[backButton setBackgroundImage:stretchableBackButtonPressed forState:UIControlStateSelected];
NSString *buttonTitle = NSLocalizedString(@"Back", @"Back");
[backButton setTitle:buttonTitle forState:UIControlStateNormal];
[backButton setTitle:buttonTitle forState:UIControlStateSelected];
backButton.titleEdgeInsets = UIEdgeInsetsMake(0, 5, 2, 1); // Tweak the text position
NSInteger width = ([backButton.titleLabel.text sizeWithFont:backButton.titleLabel.font].width + backButton.titleEdgeInsets.right +backButton.titleEdgeInsets.left);
[backButton setFrame:CGRectMake(0, 0, width, 29)];
backButton.titleLabel.font = [UIFont boldSystemFontOfSize:13.0f];
[backButton addTarget:self action:@selector(yourSelector:) forControlEvents:UIControlEventTouchDown];
// Now add the button as a custom UIBarButtonItem
UIBarButtonItem *backButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:backButton] autorelease];
self.navigationItem.leftBarButtonItem = backButtonItem;

Here's what I ended up doing after searching through all these solutions and others. It uses a stretchable png's extracted from the UIKit stock images. This way you can set the text to whatever you liek

// Generate the background images
UIImage *stretchableBackButton = [[UIImage imageNamed:@"UINavigationBarDefaultBack.png"] stretchableImageWithLeftCapWidth:14 topCapHeight:0];
UIImage *stretchableBackButtonPressed = [[UIImage imageNamed:@"UINavigationBarDefaultBackPressed.png"] stretchableImageWithLeftCapWidth:13 topCapHeight:0];
// Setup the UIButton
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
[backButton setBackgroundImage:stretchableBackButton forState:UIControlStateNormal];
[backButton setBackgroundImage:stretchableBackButtonPressed forState:UIControlStateSelected];
NSString *buttonTitle = NSLocalizedString(@"Back", @"Back");
[backButton setTitle:buttonTitle forState:UIControlStateNormal];
[backButton setTitle:buttonTitle forState:UIControlStateSelected];
backButton.titleEdgeInsets = UIEdgeInsetsMake(0, 5, 2, 1); // Tweak the text position
NSInteger width = ([backButton.titleLabel.text sizeWithFont:backButton.titleLabel.font].width + backButton.titleEdgeInsets.right +backButton.titleEdgeInsets.left);
[backButton setFrame:CGRectMake(0, 0, width, 29)];
backButton.titleLabel.font = [UIFont boldSystemFontOfSize:13.0f];
[backButton addTarget:self action:@selector(yourSelector:) forControlEvents:UIControlEventTouchDown];
// Now add the button as a custom UIBarButtonItem
UIBarButtonItem *backButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:backButton] autorelease];
self.navigationItem.leftBarButtonItem = backButtonItem;
分分钟 2024-07-14 22:20:22

使用 Xcode 5.x 中的 Interface Builder 可以轻松实现

Result

  • 使用对象库中的工具栏栏按钮项

    Components

  • 按钮的 < strong>属性检查器编辑图像部分
    带有您的后退按钮图像

    属性检查器

完成!

It's easy to do with Interface Builder in Xcode 5.x

Result

  • use Toolbar and Bar Button Item from Object library

    Components

  • in button's Attributes inspector edit Image section
    with your back button image

    Attributes inspector

Done!

懵少女 2024-07-14 22:20:22

Swift 5.2 Xcode 11.4

Apple 符号 chevron.left 现在允许使用更优雅的解决方案来制作自定义按钮。 我已尽可能接近地匹配尺寸和间距。

输入图片此处描述

import UIKit

class CustomBackButton: UIBarButtonItem {

    convenience init(target: Any, selector: Selector) {

        // Create UIButton
        let button = UIButton(frame: .zero)

        // Customise Title
        button.setTitle("Back", for: .normal)
        button.setTitleColor(.systemBlue, for: .normal)
        button.titleLabel?.font = UIFont.systemFont(ofSize: 17)

        // Customise Image
        let config = UIImage.SymbolConfiguration(pointSize: 19.0, weight: .semibold, scale: .large)
        let image = UIImage(systemName: "chevron.left", withConfiguration: config)
        button.setImage(image, for: .normal)

        // Add Target
        button.addTarget(target, action: selector, for: .touchUpInside)

        // Customise Spacing to match system Back button
        button.imageEdgeInsets = UIEdgeInsets(top: 0.0, left: -18.0, bottom: 0.0, right: 0.0)
        button.titleEdgeInsets = UIEdgeInsets(top: 0.0, left: -12.0, bottom: 0.0, right: 0.0)

        self.init(customView: button)
    }
}

这可以作为 UIToolbarItemUINavigationItem 实现,

override func viewDidLoad() {
    super.viewDidLoad()

    // UIToolbar Item
    let barBackButton = CustomBackButton(target: self, selector: #selector(backButtonTapped))
    let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
    navigationController?.setToolbarHidden(false, animated: false)
    toolbarItems = [barBackButton, flexSpace]

    // Navigation Item
    let navBackButton = CustomBackButton(target: self, selector: #selector(backButtonTapped))
    navigationItem.leftBarButtonItem = navBackButton
}

@objc func backButtonTapped() {
    print("Back tapped")
}

如果您想翻转按钮并使箭头指向右侧:

输入图片此处描述

使用名为 "chevron.right" 的 Apple 符号

将以下代码添加到 CustomBackButton 类中:

    // Put the image of the right side of the button
    button.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
    button.titleLabel?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
    button.imageView?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)

Swift 5.2 Xcode 11.4

The Apple Symbol chevron.left now allows a more elegant solution to make a custom button. I have matched the size and spacing as close as possible.

enter image description here

import UIKit

class CustomBackButton: UIBarButtonItem {

    convenience init(target: Any, selector: Selector) {

        // Create UIButton
        let button = UIButton(frame: .zero)

        // Customise Title
        button.setTitle("Back", for: .normal)
        button.setTitleColor(.systemBlue, for: .normal)
        button.titleLabel?.font = UIFont.systemFont(ofSize: 17)

        // Customise Image
        let config = UIImage.SymbolConfiguration(pointSize: 19.0, weight: .semibold, scale: .large)
        let image = UIImage(systemName: "chevron.left", withConfiguration: config)
        button.setImage(image, for: .normal)

        // Add Target
        button.addTarget(target, action: selector, for: .touchUpInside)

        // Customise Spacing to match system Back button
        button.imageEdgeInsets = UIEdgeInsets(top: 0.0, left: -18.0, bottom: 0.0, right: 0.0)
        button.titleEdgeInsets = UIEdgeInsets(top: 0.0, left: -12.0, bottom: 0.0, right: 0.0)

        self.init(customView: button)
    }
}

This can be implemented either as a UIToolbarItem, or a UINavigationItem

override func viewDidLoad() {
    super.viewDidLoad()

    // UIToolbar Item
    let barBackButton = CustomBackButton(target: self, selector: #selector(backButtonTapped))
    let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
    navigationController?.setToolbarHidden(false, animated: false)
    toolbarItems = [barBackButton, flexSpace]

    // Navigation Item
    let navBackButton = CustomBackButton(target: self, selector: #selector(backButtonTapped))
    navigationItem.leftBarButtonItem = navBackButton
}

@objc func backButtonTapped() {
    print("Back tapped")
}

If you want to flip the button and have the arrow pointing to the Right:

enter image description here

Use Apple Symbol named "chevron.right"

Add the following code to the CustomBackButton class:

    // Put the image of the right side of the button
    button.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
    button.titleLabel?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
    button.imageView?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
冬天旳寂寞 2024-07-14 22:20:22

我试图做同样的事情,但我希望后退按钮位于导航栏中。 (我实际上需要一个后退按钮,它的作用不仅仅是返回,所以我必须使用 leftBarButtonItem 属性)。 我尝试了 AndrewS 的建议,但在导航栏中,它看起来不像应有的样子,因为 UIButton 有点被转换为 UIBarButtonItem。

但我找到了解决这个问题的方法。 我实际上只是在 UIButton 下放置了一个 UIView 并为 UIBarButtonItem 设置了 customView。 这是代码,如果有人需要的话:

// initialize button and button view
UIButton *backButton = [UIButton buttonWithType:101];
UIView *backButtonView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, backButton.frame.size.width, backButton.frame.size.height)];

[backButton addTarget:self action:@selector(backButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
[backButton setTitle:@"Back" forState:UIControlStateNormal];
[backButtonView addSubview:backButton];

// set buttonview as custom view for bar button item
UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButtonView];
self.navigationItem.leftBarButtonItem = backButtonItem;

// push item to navigationbar items
[self.navigationController.navigationBar setItems:[NSArray arrayWithObject:backButtonItem]];

I was trying to do the same thing, but I wanted the back button to be in the navigation bar. (I actually needed a back button, that would do more than only going back, so I had to use the leftBarButtonItem property). I tried what AndrewS suggested, but in the navigation bar it wouldn't look the way it should, as the UIButton was kind of casted to a UIBarButtonItem.

But I found a way to work around this. I actually just put a UIView under the UIButton and set the customView for the UIBarButtonItem. Here is the code, if somebody needs it:

// initialize button and button view
UIButton *backButton = [UIButton buttonWithType:101];
UIView *backButtonView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, backButton.frame.size.width, backButton.frame.size.height)];

[backButton addTarget:self action:@selector(backButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
[backButton setTitle:@"Back" forState:UIControlStateNormal];
[backButtonView addSubview:backButton];

// set buttonview as custom view for bar button item
UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButtonView];
self.navigationItem.leftBarButtonItem = backButtonItem;

// push item to navigationbar items
[self.navigationController.navigationBar setItems:[NSArray arrayWithObject:backButtonItem]];
懷念過去 2024-07-14 22:20:22

要为 UIToolbar 创建图像,请在 Photoshop 中制作一个 png,只要有任何颜色,它就会将其设置为白色,如果 alpha = 0,则将其保留。

SDK 实际上将边框放在您制作的图标周围,并将其变成白色,而无需您执行任何操作。

看,这就是我在 Photoshop 中为前进按钮制作的内容(显然将其替换为后退按钮):

http://twitpic .com/1oanv

这就是 Interface Builder 中的样子

http://twitpic.com/1oaoa< /a>

To create an image for the UIToolbar, make a png in photoshop and WHERE EVER there is ANY colour it puts it white, and where it's alpha = 0 then it leaves it alone.

The SDK actually put's the border around the icon you have made and turns it white without you having to do anything.

See, this is what I made in Photoshop for my forward button (obviously swap it around for back button):

http://twitpic.com/1oanv

and this is what it appeared like in Interface Builder

http://twitpic.com/1oaoa

贵在坚持 2024-07-14 22:20:22

不使用 png 的解决方案。 基于这个答案:将小箭头添加到 iPhone TableView 单元格中单元格的右侧

只需水平翻转 UITableViewCell 即可!

UIButton *btnBack = [[UIButton alloc] initWithFrame:CGRectMake(0, 5, 70, 20)];

// Add the disclosure
CGRect frm;
UITableViewCell *disclosure = [[UITableViewCell alloc] init];
disclosure.transform = CGAffineTransformScale(CGAffineTransformIdentity, -1, 1);
frm = self.btnBack.bounds;
disclosure.frame = CGRectMake(frm.origin.x, frm.origin.y, frm.size.width-25, frm.size.height);
disclosure.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
disclosure.userInteractionEnabled = NO;
[self.btnBack addSubview:disclosure];

// Add the label
UILabel *lbl = [[UILabel alloc] init];
frm = CGRectOffset(self.btnBack.bounds, 15, 0);
lbl.frame = frm;
lbl.textAlignment = NSTextAlignmentCenter;
lbl.text = @"BACK";
[self addSubview:lbl];

Solution WITHOUT using a png. Based on this SO answer: Adding the little arrow to the right side of a cell in an iPhone TableView Cell

Just flipping the UITableViewCell horizontally!

UIButton *btnBack = [[UIButton alloc] initWithFrame:CGRectMake(0, 5, 70, 20)];

// Add the disclosure
CGRect frm;
UITableViewCell *disclosure = [[UITableViewCell alloc] init];
disclosure.transform = CGAffineTransformScale(CGAffineTransformIdentity, -1, 1);
frm = self.btnBack.bounds;
disclosure.frame = CGRectMake(frm.origin.x, frm.origin.y, frm.size.width-25, frm.size.height);
disclosure.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
disclosure.userInteractionEnabled = NO;
[self.btnBack addSubview:disclosure];

// Add the label
UILabel *lbl = [[UILabel alloc] init];
frm = CGRectOffset(self.btnBack.bounds, 15, 0);
lbl.frame = frm;
lbl.textAlignment = NSTextAlignmentCenter;
lbl.text = @"BACK";
[self addSubview:lbl];
長街聽風 2024-07-14 22:20:22

如果您想避免自己绘制它,您可以使用未记录的类:具有样式 1 的 UINavigationButton。当然,这可能会阻止您的应用程序被批准......
/约翰

If you want to avoid drawing it yourself, you could use the undocumented class: UINavigationButton with style 1. This could, of course, stop your application from being approved...
/John

南七夏 2024-07-14 22:20:22

好吧,您不必为每种尺寸使用不同的按钮,您可以使用 [UIImagestretchableImageWithLeftCapWidth:topCapHeight:],但我唯一发现的是自定义图像。

Well, you don't have to have a different button for every size, you can use [UIImage stretchableImageWithLeftCapWidth:topCapHeight:], but the only thing I've found is custom images.

那些过往 2024-07-14 22:20:22

我遇到了类似的问题,并推出了一个库PButton。 示例是类似后退导航按钮的按钮,可以像自定义按钮一样在任何地方使用。

像这样的事情:
在此处输入图像描述

I had a similar problem, and come out one library PButton. And the sample is the back navigation button like button, which can be used anywhere just like a customized button.

Something like this:
enter image description here

逆光飞翔i 2024-07-14 22:20:22

Swift 3 中的示例,右上角有上一个和下一个按钮。

let prevButtonItem = UIBarButtonItem(title: "\u{25C0}", style: .plain, target: self, action: #selector(prevButtonTapped))
let nextButtonItem = UIBarButtonItem(title: "\u{25B6}", style: .plain, target: self, action: #selector(nextButtonTapped))
self.navigationItem.rightBarButtonItems = [nextButtonItem, prevButtonItem]

Example in Swift 3, with a previous and a next button in the top right.

let prevButtonItem = UIBarButtonItem(title: "\u{25C0}", style: .plain, target: self, action: #selector(prevButtonTapped))
let nextButtonItem = UIBarButtonItem(title: "\u{25B6}", style: .plain, target: self, action: #selector(nextButtonTapped))
self.navigationItem.rightBarButtonItems = [nextButtonItem, prevButtonItem]
忘东忘西忘不掉你 2024-07-14 22:20:22

迅速

// create button
    var backButton = UIButton(type: 101)

    // left-pointing shape!
    backButton.addTarget(self, action: #selector(self.backAction), for: .touchUpInside)
    backButton.setTitle("Back", for: .normal)

    // create button item -- possible because UIButton subclasses UIView!
    var backItem = UIBarButtonItem(customView: backButton)

    // add to toolbar, or to a navbar (you should only have one of these!)
    toolbar.items = [backItem]
    navItem.leftBarButtonItem = backItem

Swift

// create button
    var backButton = UIButton(type: 101)

    // left-pointing shape!
    backButton.addTarget(self, action: #selector(self.backAction), for: .touchUpInside)
    backButton.setTitle("Back", for: .normal)

    // create button item -- possible because UIButton subclasses UIView!
    var backItem = UIBarButtonItem(customView: backButton)

    // add to toolbar, or to a navbar (you should only have one of these!)
    toolbar.items = [backItem]
    navItem.leftBarButtonItem = backItem
陌伤浅笑 2024-07-14 22:20:22

尝试这个。 我确信您不需要后退按钮图像来创建这样的图像。

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Back"
                                                               style:UIBarButtonItemStyleBordered
                                                              target:self
                                                              action:@selector(yourSelectorGoesHere:)];
self.navigationItem.backBarButtonItem = backButton;

这就是你所要做的:)

Try this. I am sure you do not need a back button image to create one such.

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Back"
                                                               style:UIBarButtonItemStyleBordered
                                                              target:self
                                                              action:@selector(yourSelectorGoesHere:)];
self.navigationItem.backBarButtonItem = backButton;

That's all you have to do :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文