如何让自定义标签栏显示标签栏项目在 Xcode 中设置的选定图像?

Posted

技术标签:

【中文标题】如何让自定义标签栏显示标签栏项目在 Xcode 中设置的选定图像?【英文标题】:How to get a custom tab bar to display a tab bar item's selected image set in Xcode? 【发布时间】:2017-03-13 02:05:25 【问题描述】:

我创建了一个自定义标签栏,可以正确显示标签栏项目。当我选择一个选项卡/图标时,会显示选项卡栏项目的视图控制器,但图标不会更改为“选定图像”图标,即显示其视图控制器时图标不会更改。

我做错了什么?如何让图标更新为我在 IB 上设置为选定图像的图像?

这是我的一些代码:

class CustomTabBarController: UITabBarController, CustomTabBarDataSource, CustomTabBarDelegate 
 override func viewDidLoad() 
  super.viewDidLoad()
  self.tabBar.isHidden = true
  let customTabBar = CustomTabBar(frame: self.tabBar.frame)
  customTabBar.datasource = self
  customTabBar.delegate = self
  customTabBar.setup()
  self.view.addSubview(customTabBar)
 
 // MARK: - CustomTabBarDataSource
 func tabBarItemsInCustomTabBar(_ tabBarView: CustomTabBar) -> [UITabBarItem] 
  return tabBar.items!
 
 // MARK: - CustomTabBarDelegate
 func didSelectViewController(_ tabBarView: CustomTabBar, atIndex index: Int) 
  self.selectedIndex = index
    



class CustomTabBar: UIView 
 var tabBarItems: [UITabBarItem]!
 var customTabBarItems: [CustomTabBarItem]!
 var tabBarButtons: [UIButton]!

func setup() 
 tabBarItems = datasource.tabBarItemsInCustomTabBar(self)
 customTabBarItems = []
 tabBarButtons = []
 let containers = createTabBarItemContainers()
 createTabBarItems(containers)


func createTabBarItems(_ containers: [CGRect]) 

var index = 0
 for item in tabBarItems 
  let container = containers[index]
  let customTabBarItem = CustomTabBarItem(frame: container)
  customTabBarItem.setup(item)
  self.addSubview(customTabBarItem)
  customTabBarItems.append(customTabBarItem)
  let button = UIButton(frame: CGRect(x: 0, y: 0, width: container.width, height: container.height))
  button.addTarget(self, action: #selector(CustomTabBar.barItemTapped(_:)), for: UIControlEvents.touchUpInside)
  customTabBarItem.addSubview(button)
  tabBarButtons.append(button)
  index += 1
 


func barItemTapped(_ sender : UIButton) 
 let index = tabBarButtons.index(of: sender)!
 delegate.didSelectViewController(self, atIndex: index)

【问题讨论】:

图片是否存在于 Assets.xcassets 中? 而且,您将CustomTabBar 类设置为UIView 的子类而不是UITabBar 有什么原因吗? 【参考方案1】:

改变

class CustomTabBar: UIView 

到:

class CustomTabBar: UITabBar 

然后您的自定义标签栏将像一个标签栏!

【讨论】:

【参考方案2】:

嗯,我有类似的功能,并像这样用 UITabBarController 实现。

enum TabType:Int
case viewController1 = 0
case viewController2 = 1
case viewController3 = 2


class CustomTabbarVC: UITabBarController 

    override func viewDidLoad() 
        super.viewDidLoad()
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

    convenience init(userType : UserType)
        self.init()
        addViewControllers()
        setupOnInit()

        let tabBar = self.tabBar
        tabBar.selectionIndicatorImage = UIImage().createSelectionIndicator(UIColor(red: 22/255, green: 52/255, blue: 89/255, alpha: 1.0), size: CGSize(width: tabBar.frame.width/CGFloat(tabBar.items!.count), height: tabBar.frame.height), lineWidth: 3.0)
    


    func setupOnInit()

        delegate = self
        tabBar.barStyle = UIBarStyle.black
        tabBar.isTranslucent = false
    

    func addViewControllers()

        // We will add 3 controllers

        let viewController1 = viewController1(nibName: “viewController1”, bundle: nil)
        let viewController2 = viewController2(nibName: “viewController2”, bundle: nil)
        let viewController3 = viewController3(nibName: “viewController3”, bundle: nil)

        let viewController1Navigation =  UINavigationController(rootViewController: viewController1)
        viewController1Navigation.tabBarItem = getTabbarItem(.viewController1)
        viewController1Navigation.tabBarItem.imageInsets = UIEdgeInsetsMake(6, 0, -6, 0)

        let viewController2Navigation =  UINavigationController(rootViewController: viewController2)
        viewController2Navigation.tabBarItem = getTabbarItem(.viewController2)
        viewController2Navigation.tabBarItem.imageInsets = UIEdgeInsetsMake(6, 0, -6, 0)

        let viewController3Navigation =  UINavigationController(rootViewController: viewController3)
        viewController3Navigation.tabBarItem = getTabbarItem(.viewController3)
        viewController3Navigation.tabBarItem.imageInsets = UIEdgeInsetsMake(6, 0, -6, 0)

        viewControllers = [viewController1Navigation,viewController2Navigation,viewController3Navigation]

    


    func getTabbarItem(_ tabType:TabType)->UITabBarItem

        // Fetch tab bar item and set image according to it.

        var image = String()
        var selectedImage = String()

        if tabType == .viewController1
            image = “img_viewController1_tab_nonSelected”
            selectedImage = “img_viewController1_tab_Selected”
        else if tabType == .viewController2
            image = “img_viewController2_tab_nonSelected”
            selectedImage = “img_viewController2_tab_Selected”
        else if tabType == .viewController3
            image = “img_viewController3_tab_nonSelected”
            selectedImage = “img_viewController3_tab_Selected”
        else
            print("Unknown tab type")
        

        if let imageName:String = image,let selectedImageName:String = selectedImage
            return UITabBarItem(title: nil, image: UIImage(named: imageName)?.withRenderingMode(.alwaysOriginal), selectedImage: UIImage(named: selectedImageName)?.withRenderingMode(.alwaysOriginal))
        else
            return UITabBarItem()
        
    



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

如何在 App delegate 中实现

class AppDelegate: UIResponder, UIApplicationDelegate

    var window: UIWindow?
    var customTabbarVC: CustomTabbarVC?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 

         window = UIWindow(frame: UIScreen.main.bounds)
         customTabbarVC = customTabbarVC() // It will invoke init methods of customtabbarvc
         window?.rootViewController = customTabbarVC // Here your tab bar controller will setup 

        return true
     

  // Other APP DELEGATE METHODS


如果您有任何问题,请告诉我..

【讨论】:

【参考方案3】:

要在单击按钮后更改自定义标签栏按钮中的图像,您需要编写代码以更改以下函数中的图像

func barItemTapped(_ sender : UIButton) 

类似

 func barItemTapped(_ sender : UIButton) 

    if sender.tag == 1
    
    tabBarButtons.setImage(UIImage(named:"FirstImage.png"), forState: .Normal)
    
    else
    
    tabBarButtons.setImage(UIImage(named:"SecImage.png"), forState: .Normal)
    
 

【讨论】:

以上是关于如何让自定义标签栏显示标签栏项目在 Xcode 中设置的选定图像?的主要内容,如果未能解决你的问题,请参考以下文章

标签栏项目图像不显示 - xcode 6 [关闭]

Swift 和 Xcode - 如何创建自定义标签栏图标

标签栏图像显示在 Xcode 中,但不在应用程序中

Xcode 导航栏、标签栏、表格视图标题未显示

iOS:旧标签栏图标显示

Xcode 旧标签栏图标突然出现