更改所选TabBarItem字体的iOS方法

10

我有一个 TabBar。我正在尝试对其进行样式设置,以使 TabBarItems 上的标题在正常状态和选定状态下具有不同的字体。对于正常状态,我想要 Helvetica Neue Light 字体,对于选定状态,我想要 Helvetica Neue Medium 字体。无论我做什么,似乎都不能让这两个状态下的字体< strong>不同。颜色更改很好用。这是我目前的设置:

  // Set the tab bar title appearance for normal state.
  [[UITabBarItem appearance] setTitleTextAttributes:@{
     NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue-Light"
                                          size:16],
     NSForegroundColorAttributeName: [CMK8Colors grayColor]
   }
                                           forState:UIControlStateNormal];

  // Set the tab bar title appearance for selected state.
  [[UITabBarItem appearance] setTitleTextAttributes:@{
     NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue-Medium"
                                          size:16],
     NSForegroundColorAttributeName: [CMK8Colors blueColor]
   }
                                           forState:UIControlStateSelected];

请帮忙。

5个回答

12

好消息和坏消息。

坏消息,它比仅使用外观代理要难一些。

好消息是,它并不比外观代理难太多!

标题

#import <UIKit/UIKit.h>

@interface MYTabbyViewController : UITabBarController

@end

实现

#import "MYTabbyViewController.h"

@implementation MYTabbyViewController

-(void)setSelectedViewController:(UIViewController *)selectedViewController
{
    [super setSelectedViewController:selectedViewController];

    for (UIViewController *viewController in self.viewControllers) {
        if (viewController == selectedViewController) {
            [viewController.tabBarItem setTitleTextAttributes:@{
                                                    NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue-Medium" size:16],
                                                    NSForegroundColorAttributeName: [UIColor blueColor]
                                                    }
                                         forState:UIControlStateNormal];
        } else {
            [viewController.tabBarItem setTitleTextAttributes:@{
                                                    NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue-Light" size:16],
                                                    NSForegroundColorAttributeName: [UIColor grayColor]
                                                    }
                                         forState:UIControlStateNormal];
        }
    }
}

你需要的最后一部分是使用这个子类而不是现成的UITabBarController。如果你正在使用Storyboards,只需选择TabBarController,进入Identity Inspector(右侧面板中的第三个子标签),并将UITabBarController更改为MYTabBarController或其他名称。

总之,就是要更新ViewController的tabBarItem!


“子类化UITabBarController并重写setCurrentViewController方法,更新即将被选中的ViewController的tabBarItem”听起来很有前途。我是iOS新手,如果您提供一个代码示例,我会选择这个答案=) - clocksmith
这个可以工作,但只有在第一次选择后,当选项卡栏出现时。由于它不会触发selectedViewController,因此保持正常状态字体。 - Sonia Casas
@SoniaCasas 你是说最初选择的tabBarItem外观不正确吗? - Acey
@Acey 没错,因为 selectedViewController 还没有被设置。 我在 iOS 10、11 和 12 中尝试过,结果都一样。 - Sonia Casas

8

@Acey的回答几乎完美,但只在第一次选择tabBarItem后更改字体,因此当创建tabBar时,在那一刻选定的tabBarItem将不会有不同的字体。为了实现这一点,我还在selectedIndex变量中添加了一个didSet

这是完整的代码(Swift 4.2)

final class TabBarController: UITabBarController {

override var selectedIndex: Int {
    didSet {
        guard let selectedViewController = viewControllers?[selectedIndex] else {
            return
        }
        selectedViewController.tabBarItem.setTitleTextAttributes([.font: UIFont.systemFont(ofSize: 11, weight: UIFontWeightHeavy)], for: .normal)
    }
}

override var selectedViewController: UIViewController? {
    didSet {

        guard let viewControllers = viewControllers else {
            return
        }

        for viewController in viewControllers {

            if viewController == selectedViewController {

                let selected: [NSAttributedString.Key: AnyObject] =
                    [.font: UIFont.systemFont(ofSize: 11, weight: UIFontWeightHeavy)]

                viewController.tabBarItem.setTitleTextAttributes(selected, for: .normal)

            } else {

                let normal: [NSAttributedString.Key: AnyObject] =
                    [.font: UIFont.systemFont(ofSize: 11)]

                viewController.tabBarItem.setTitleTextAttributes(normal, for: .normal)

            }
        }
    }
}

}


6

@Acey在Swift 3中的回答:

    override var selectedViewController: UIViewController? {
    didSet {

        guard let viewControllers = viewControllers else {
            return
        }

        for viewController in viewControllers {

            if viewController == selectedViewController {

                let selected: [String: AnyObject] =
                    [NSFontAttributeName: UIFont.systemFont(ofSize: 11, weight: UIFontWeightHeavy),
                     NSForegroundColorAttributeName: UIColor.red]

                viewController.tabBarItem.setTitleTextAttributes(selected, for: .normal)

            } else {

                let normal: [String: AnyObject] =
                    [NSFontAttributeName: UIFont.systemFont(ofSize: 11),
                     NSForegroundColorAttributeName: UIColor.blue]

                viewController.tabBarItem.setTitleTextAttributes(normal, for: .normal)

            }
        }
    }
}

1

setSelected和setHighlighted不能用于UIBarButtonItems。

使用UIBarButtonItem的

- (void)setBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics 

这里是文档 - https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIBarButtonItem_Class/Reference/Reference.html 或者,可以使用UIButton。
UIButton *myButton = [UIButton buttonWithType: UIButtonTypeRoundedRect];
[myButton setTitle:@"Info" forState:UIControlStateNormal];
[myButton setFont:[UIFont fontWithName:<font name> size:<font size>]];

[myButton setTitleColor:<color>;
myButton =  <frame>;
[myButton addTarget:self.webView action:@selector(<action>:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem * barButtonItem = [[UIBarButtonItem alloc]initWithCustomView:myButton];
[[UIBarButtonItem appearance] setTintColor:<color>;
[self.toolbar setItems:[NSArray arrayWithObjects: spaceItem, barButtonItem, nil]];

1
我不是在尝试更改背景图片,而是在尝试更改字体。在您提供的文档中,并没有提到字体。 - clocksmith
正确,但这是一种提供所选效果的方法。您还可以在工具栏中添加一个带有自定义视图的按钮。然后您可以轻松更改字体。我也会将该选项更新到答案中。 - hackerinheels
实际上,我很抱歉我误读了你的帖子。我还没有尝试过在选项卡栏中使用这个解决方案。请看一下这篇文章(http://www.appcoda.com/ios-programming-how-to-customize-tab-bar-background-appearance/)- 如果这不起作用,请告诉我...我会删除我的答案并帮助您解决问题。 - hackerinheels

0

Swift 5+

定义您的普通和选定属性:

private let attributesNormal: [NSAttributedString.Key: Any] = [
    .font: UIFont.systemFont(ofSize: 12, weight: .regular),
    .foregroundColor: UIColor.black.withAlphaComponent(0.9)]

private let attributesSelected: [NSAttributedString.Key: Any] = [
    .font: UIFont.systemFont(ofSize: 12, weight: .semibold),
    .foregroundColor: UIColor.black]

unselectedItemTintColor设置任何颜色。如果没有这个,attributesNormal中定义的颜色将无法工作。不要问我为什么。

tabBar.unselectedItemTintColor = .black

然后在你的UITabBarController中,重写selectedIndexselectedViewController

override var selectedIndex: Int {
    didSet {
        guard let vc = viewControllers[selectedIndex] else { return }
        vc.tabBarItem.setTitleTextAttributes(attributesNormal, for: .normal)
    }
}

override var selectedViewController: UIViewController? {
    didSet {
        viewControllers?.forEach {
            let attributes = $0 == selectedViewController ? attributesSelected : attributesNormal
            $0.tabBarItem.setTitleTextAttributes(attributes, for: .normal)
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接