如何让UITabBar选择指标图像填满整个空间?

时间:2015-11-23 09:59:35

标签: ios swift uiimage uitabbarcontroller

我有一个UITabBarController,我使用此代码设置选择指标图像:

let selectedBG = UIImage(named:"tabbarbgtest.png")?.resizableImageWithCapInsets(UIEdgeInsetsMake(0, 0, 0, 0))
UITabBar.appearance().selectionIndicatorImage = selectedBG

但是图像并没有填满整个空间 - 见下图:

enter image description here

图像只是一个红色正方形,在82x49px上有解决方案,但是图像更宽,它仍然不能填满整个空间。希望你们能帮忙 - 谢谢。

6 个答案:

答案 0 :(得分:30)

如果你想在标签选择上设置红色图像我会建议你设置活动标签栏项目的背景颜色,根据我的意见,只要你能用编码做你的东西,为什么要使用图像这样才能更好地设置选择颜色而不是图像。 您可以使用以下代码实现此目的。

    // set red as selected background color
    let numberOfItems = CGFloat(tabBar.items!.count)
    let tabBarItemSize = CGSize(width: tabBar.frame.width / numberOfItems, height: tabBar.frame.height)
    tabBar.selectionIndicatorImage = UIImage.imageWithColor(color: UIColor.red, size: tabBarItemSize).resizableImage(withCapInsets: .zero)

    // remove default border
    tabBar.frame.size.width = self.view.frame.width + 4
    tabBar.frame.origin.x = -2

使用UIImage的以下扩展名:

extension UIImage {
    class func imageWithColor(color: UIColor, size: CGSize) -> UIImage {
        let rect: CGRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        UIGraphicsBeginImageContextWithOptions(size, false, 0)
        color.setFill()
        UIRectFill(rect)
        let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return image
    }
}

希望能帮助你。

另一种方式就在这里:

在你的tabBarController中,你可以设置默认的UITabBar tintColor,barTintColor,selectionIndicatorImage(在这里作弊)和renderMode的图像,见下面的评论:

    class MyTabBarController: UITabBarController, UINavigationControllerDelegate {
    ...
    override func viewDidLoad() {
        ...
            // Sets the default color of the icon of the selected UITabBarItem and Title
            UITabBar.appearance().tintColor = UIColor.red
        // Sets the default color of the background of the UITabBar
        UITabBar.appearance().barTintColor = UIColor.black

        // Sets the background color of the selected UITabBarItem (using and plain colored UIImage with the width = 1/5 of the tabBar (if you have 5 items) and the height of the tabBar)
        UITabBar.appearance().selectionIndicatorImage = UIImage().makeImageWithColorAndSize(color: UIColor.blue, size: CGSize(width: tabBar.frame.width/5, height: tabBar.frame.height))

        // Uses the original colors for your images, so they aren't not rendered as grey automatically.
        for item in (self.tabBar.items)! {
        if let image = item.image {
            item.image = image.withRenderingMode(.alwaysOriginal)
        }
    }
    }
    ...
}

并且你想要扩展UIImage类来制作你需要的大小的纯色图像:

 extension UIImage {
    func makeImageWithColorAndSize(color: UIColor, size: CGSize) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(size, false, 0)
        color.setFill()
        UIRectFill(CGRect(x: 0, y: 0, width: size.width, height: size.height))
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image!
    }
}

答案 1 :(得分:8)

截至2017年,老实说Piyush的回答对我不起作用。在寻找另一种解决方案几天后,我找到了我的 - by subclassing the UITabBarController.

即使旋转,它也适用于多个设备。

备注

  1. 将图片的渲染模式设为Original
  2. 如果您以编程方式进行屏幕,请将以下类分配给Storyboard中的UITabBarController或基类。

    //
    //  BaseTabBarController.swift
    //  MyApp
    //
    //  Created by DRC on 1/27/17.
    //  Copyright © 2017 PrettyITGirl. All rights reserved.
    //
    
    import UIKit
    
    class BaseTabBarController: UITabBarController {
    
        let numberOfTabs: CGFloat = 4
        let tabBarHeight: CGFloat = 60
    
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
    
            updateSelectionIndicatorImage()
        }
    
        override func viewWillLayoutSubviews() {
            super.viewWillLayoutSubviews()
    
            updateSelectionIndicatorImage()
        }
    
        func updateSelectionIndicatorImage() {
            let width = tabBar.bounds.width
            var selectionImage = UIImage(named:"myimage.png")
            let tabSize = CGSize(width: width/numberOfTabs, height: tabBarHeight)
    
            UIGraphicsBeginImageContext(tabSize)
            selectionImage?.draw(in: CGRect(x: 0, y: 0, width: tabSize.width, height: tabSize.height))
            selectionImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
    
            tabBar.selectionIndicatorImage = selectionImage
        }
    
    }
    

答案 2 :(得分:1)

您应该查看this以使tabbarbgtest.png可调整大小,然后将图像分配给selectionIndicatorImage,您甚至可以在storyboard编辑器中执行此操作。

答案 3 :(得分:1)

要支持iPhone X(以下代码适用于所有版本),请在viewDidLayoutSubviews()中编写代码。

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    let tabWidth = (tabBar.frame.width/CGFloat(tabBar.items!.count))
    let tabHeight = tabBar.frame.height
    self.tabBar.selectionIndicatorImage = imageWithColor(color: UIColor.white, size: CGSize(width: tabWidth, height: tabHeight)).resizableImage(withCapInsets: UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0))
 }

来源:https://github.com/Ramotion/animated-tab-bar/issues/191

答案 4 :(得分:0)

目标c中的这种相对简单的解决方案对我来说适用于iPhone X,不难转换为快速解决方案:

CGFloat bottomPadding = 0;

if (@available(iOS 11.0, *)) {
  UIWindow *window = UIApplication.sharedApplication.keyWindow;
  bottomPadding = window.safeAreaInsets.bottom;
}

[UITabBar.appearance setSelectionIndicatorImage:[UIImage imageWithColor:[UIColor lightGrayColor] 
          andBounds:CGRectMake(0, 0, self.tabBar.frame.size.width/5, self.tabBar.frame.size.height + bottomPadding)]];

答案 5 :(得分:0)

这是对以上Glenn's solution的改编...

    import UIKit

    class BaseTabBarController: UITabBarController {

        var tabBarBounds: CGRect? {
            didSet {
                guard tabBarBounds != oldValue else { return }
                updateSelectionIndicatorColor(UIColor.green)
            }
        }

        override func viewWillLayoutSubviews() {
            super.viewWillLayoutSubviews()
            tabBarBounds = tabBar.bounds
        }

        func updateSelectionIndicatorColor(_ tintColor: UIColor) {
            guard let tabBarItems = self.tabBar.items else { return }

            let tabWidth = tabBar.bounds.width
            let tabHeight = tabBar.bounds.height
            let tabSize = CGSize(width: tabWidth / CGFloat(tabBarItems.count), height: tabHeight)
            var selectionImage = UIImage(color: tintColor, size: tabSize)

            UIGraphicsBeginImageContext(tabSize)
            selectionImage?.draw(in: CGRect(x: 0, y: 0, width: tabSize.width, height: tabSize.height))
            selectionImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()

            tabBar.selectionIndicatorImage = selectionImage
        }

    }

    public extension UIImage {
        public convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) {
            let rect = CGRect(origin: .zero, size: size)
            UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
            color.setFill()
            UIRectFill(rect)
            let image = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()

            guard let cgImage = image?.cgImage else { return nil }
            self.init(cgImage: cgImage)
        }
    }