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

据我所知,获得其中一个的唯一方法是将UINavigationController保留在默认设置,它使用一个用于左侧栏项。但没有办法我可以找到创建一个作为一个UIBarButtonItem,所以我不能在一个标准的UIToolbar,即使他们非常类似于UINavigationBars。

我可以用按钮图像手动创建它,但我在任何地方都找不到源图像。它们有alpha通道边缘,所以截图和剪切不会得到非常通用的结果。

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

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

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


当前回答

Unicode方法

我认为使用unicode字符来完成工作要容易得多。你可以通过谷歌Unicode三角形或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的按钮中工作。

要获得完整的字符列表,请搜索谷歌以获取Unicode字符和所需内容。这是黑色左指向三角形的入口。

结果

其他回答

Swift 5.2 Xcode 11.4

苹果标志雪佛龙。左边现在允许一个更优雅的解决方案,使一个自定义按钮。我已经尽可能地匹配了大小和间距。

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)
    }
}

这可以实现为一个UIToolbarItem,或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")
}

如果你想翻转按钮,让箭头指向右侧:

使用命名为“chevron.right”的苹果符号

将以下代码添加到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)

首先,你必须找到后退按钮的图像。我使用了一个很好的应用程序,叫做Extractor,它可以从iPhone中提取所有的图形。 在iOS7中,我成功检索了名为UINavigationBarBackIndicatorDefault的图像,它是黑色的,因为我需要红色,所以我使用Gimp将颜色更改为红色。

编辑:

正如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];

要为UIToolbar创建一个图像,在photoshop中制作一个png,无论哪里有任何颜色,它都会把它放在白色,而当它的alpha = 0时,它就会离开它。

SDK实际上是在你所创建的图标周围设置边界,并在你不需要做任何事情的情况下将其变成白色。

看,这是我在Photoshop中为前进按钮做的(显然是把它换成后退按钮):

http://twitpic.com/1oanv

这是它在Interface Builder中出现的样子

http://twitpic.com/1oaoa

好吧,你不必为每个大小都有不同的按钮,你可以使用[UIImage stretchableImageWithLeftCapWidth:topCapHeight:],但我唯一发现的是自定义图像。

我试图做同样的事情,但我希望后退按钮在导航栏。(我实际上需要一个返回按钮,这将做的不仅仅是返回,所以我必须使用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]];