使用 swift Xcode 6 的默认选项卡栏项目颜色

Posted

技术标签:

【中文标题】使用 swift Xcode 6 的默认选项卡栏项目颜色【英文标题】:Default tab bar item colors using swift Xcode 6 【发布时间】:2014-09-23 00:48:46 【问题描述】:

环境: - Xcode 6 测试版 4 - 斯威夫特语言 - ios 选项卡式应用程序(默认 xCode 项目)

如何将选项卡的默认灰色更改为其他颜色? (最好在全球范围内)

就我的研究而言,我需要以某种方式将每个选项卡的图像渲染模式更改为原始渲染模式,但我不知道如何

【问题讨论】:

【参考方案1】:

每个(默认)标签栏项目由文本和图标组成。通过指定外观来全局更改文本颜色非常容易:

// you can add this code to you AppDelegate application:didFinishLaunchingWithOptions: 
// or add it to viewDidLoad method of your TabBarController class
UITabBarItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.magentaColor()], forState:.Normal)
UITabBarItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.redColor()], forState:.Selected)

图像情况稍微复杂一些。您不能全局定义它们的外观。您应该在 TabBarController 类中重新定义它们。在TabBarController 类的viewDidLoad 方法中添加以下代码:

for item in self.tabBar.items as [UITabBarItem] 
    if let image = item.image 
        item.image = image.imageWithColor(UIColor.yellowColor()).imageWithRenderingMode(.AlwaysOriginal)
    

我们知道 UIImage 类中没有 imageWithColor(...) 方法。所以这里是扩展实现:

// Add anywhere in your app
extension UIImage 
    func imageWithColor(tintColor: UIColor) -> UIImage 
        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)

        let context = UIGraphicsGetCurrentContext() as CGContextRef
        CGContextTranslateCTM(context, 0, self.size.height)
        CGContextScaleCTM(context, 1.0, -1.0);
        CGContextSetBlendMode(context, .Normal)

        let rect = CGRectMake(0, 0, self.size.width, self.size.height) as CGRect
        CGContextClipToMask(context, rect, self.CGImage)
        tintColor.setFill()
        CGContextFillRect(context, rect)

        let newImage = UIGraphicsGetImageFromCurrentImageContext() as UIImage
        UIGraphicsEndImageContext()

        return newImage
    

imageWithColor 是从这个答案借来的:https://***.com/a/24545102/3050466

【讨论】:

- 如果其中一个选项卡项没有图像,这将引发错误。 - 我将扩展放在我的自定义 MyTabBarController 类中,就在 class MyTabBarController 上方(起初我试图创建一个新的目标扩展..) 干杯尼克 您对nil 图像的看法是正确的。我已经用if let check 更新了代码。 我创建了选项卡式应用程序,没有 TabBarController(文件)类。我被这个“超级”IDE 搞疯了…… 默认情况下,故事板中的 TabBarController 类型为 UITabBarController。您需要在您的(让我们称之为)MyTabBarController 类中对其进行子类化,并从答案中添加代码。并且不要忘记转到情节提要,选择您的 TabBarController 并将其类设置为MyTabBarController。所以你应该创建MyTabBarController 类。作为回答,它称为 TabBarController;可能我应该重命名它以避免歧义。 @Keenle:这会改变普通图像的颜色。选择的图片呢?【参考方案2】:

我在评论 cmets 方面没有足够的声誉,但很多人对如何更改所选图像的颜色感兴趣

只需在之后添加另一个if let 检查

if let image = item.image

就像这样:

if let selectedImage = item.selectedImage 
            item.selectedImage = selectedImage.imageWithColor(UIColor.yellowColor()).imageWithRenderingMode(.AlwaysOriginal)
        

这完美地解决了这个问题。 还有一点补充,因为你需要 Swift 1.2 和 Xcode 6.3.2

for item in self.tabBar.items as! [UITabBarItem]

而不是

for item in self.tabBar.items as [UITabBarItem]

希望有帮助!

【讨论】:

当我运行模拟器时,应用程序崩溃,并且在日志中显示错误:致命错误:在展开可选值时意外发现 nil 我认为这与您使用的是 Xcode 7 和 Swift 2.0 或更高版本有关。此代码适用于 Swift 1.2 和 Xcode 6.3.2 玩转可选和展开。【参考方案3】:

Swift 2.0

要更改标签栏图像的默认颜色,请将以下代码添加到 TabBarController 类的 viewDidLoad 方法中:

for item in self.tabBar.items! as [UITabBarItem] 
    if let image = item.image 
      item.image = image.imageWithColor(UIColor.yellowColor()).imageWithRenderingMode(.AlwaysOriginal)
    

更新imageWithColor 扩展。与上述方法一起使用,应放在TabBarController 类之外:

extension UIImage 
    func imageWithColor(tintColor: UIColor) -> UIImage 
        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)

        let context = UIGraphicsGetCurrentContext()! as CGContextRef
        CGContextTranslateCTM(context, 0, self.size.height)
        CGContextScaleCTM(context, 1.0, -1.0);
        CGContextSetBlendMode(context, CGBlendMode.Normal)

        let rect = CGRectMake(0, 0, self.size.width, self.size.height) as CGRect
        CGContextClipToMask(context, rect, self.CGImage)
        tintColor.setFill()
        CGContextFillRect(context, rect)

        let newImage = UIGraphicsGetImageFromCurrentImageContext() as UIImage
        UIGraphicsEndImageContext()

        return newImage
    

文本着色方式没有变化,仅供参考。还应该将下面的代码添加到viewDidLoad

// you can add this code to you AppDelegate application:didFinishLaunchingWithOptions: 
// or add it to viewDidLoad method of your TabBarController class
UITabBarItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.magentaColor()], forState:.Normal)
UITabBarItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.redColor()], forState:.Selected)

【讨论】:

这条线let context = UIGraphicsGetCurrentContext()! as CGContextRef的安全性如何?为什么我们可以确保使用强制展开?【参考方案4】:

Swift 3.0

要更改标签栏图像的默认颜色,请将下面的代码添加到 TabBarController 类的 viewDidLoad 方法中:

    for item in self.tabBar.items! as [UITabBarItem] 
        if let image = item.image 
            item.image = image.imageWithColor(tintColor: UIColor.yellow).withRenderingMode(.alwaysOriginal)
        
    

更新imageWithColor 扩展。与上述方法一起使用,应放在TabBarController 类之外:

extension UIImage 
 func imageWithColor(tintColor: UIColor) -> UIImage 
    UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)

    let context = UIGraphicsGetCurrentContext()! as CGContext
    context.translateBy(x: 0, y: self.size.height)
    context.scaleBy(x: 1.0, y: -1.0);
    context.setBlendMode(CGBlendMode.normal)

    let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
    context.clip(to: rect, mask: self.cgImage!)
    tintColor.setFill()
    context.fill(rect)

    let newImage = UIGraphicsGetImageFromCurrentImageContext()! as UIImage
    UIGraphicsEndImageContext()

    return newImage
 

【讨论】:

以上是关于使用 swift Xcode 6 的默认选项卡栏项目颜色的主要内容,如果未能解决你的问题,请参考以下文章

如何减小 UI 选项卡栏项图像的大小以使其适合选项卡栏?

添加选项卡栏项 (UITabBar) 时 XCode 4.3 崩溃

将选项卡栏项与在其堆栈中显示第二个视图控制器的导航控制器相关联?

如何从 UIButton 到选项卡栏项?

UITabBarItem 执行 IBAction Xcode 4.2

选项卡栏项显示具有模态序列的视图控制器