Add a line as a selection indicator to a UITabbarItem in Swift

∥☆過路亽.° 提交于 2019-11-26 21:00:58

问题


I wanna use a thick line at the bottom of a UITabbarItems as a selection indicator. Due to the fact that the App must work on different phone sizes, I cannot use a image as selection indicator. That's why I think I have to use Swift to do this. (The line has to be 1/3 of page width).

I tried to use UITabBarItem.appearance() but without success.


回答1:


You can do it with add custom image, that will be created in your code, to selectionIndicatorImage on your UITabBar object. For example you can create extension for UIImage class like this:

extension UIImage {
    func createSelectionIndicator(color: UIColor, size: CGSize, lineWidth: CGFloat) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(size, false, 0)
        color.setFill()
        UIRectFill(CGRectMake(0, size.height - lineWidth, size.width, lineWidth))
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}

And call it in your first loaded ViewController like this:

class FirstViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let tabBar = self.tabBarController!.tabBar
        tabBar.selectionIndicatorImage = UIImage().createSelectionIndicator(UIColor.blueColor(), size: CGSizeMake(tabBar.frame.width/CGFloat(tabBar.items!.count), tabBar.frame.height), lineWidth: 2.0)
    }

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

In this case result will be like this:




回答2:


Swift 3:

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

override func viewDidLoad() {
    super.viewDidLoad()
    let tabBar = self.tabBarController!.tabBar
    tabBar.selectionIndicatorImage = UIImage().createSelectionIndicator(color: UIColor.blue, size: CGSize(width: tabBar.frame.width/CGFloat(tabBar.items!.count), height: tabBar.frame.height), lineHeight: 2.0)
}



回答3:


Swift 4.x
Xcode 10.x

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

Use

tabBar.selectionIndicatorImage = UIImage().createSelectionIndicator(color: BLUE, size: CGSize(width: tabBar.frame.width/CGFloat(tabBar.items!.count), height:  tabBar.frame.height), lineWidth: 2.0)



回答4:


I solved my problem.

Features of this tiny code snippet:

  • width is dynamic
  • it is animated
  • it is a lot more customizable for future features

    class FirstViewController: UIViewController {
    
    let rectShape = CAShapeLayer()
    let indicatorHeight: CGFloat = 5
    var indicatorWidth: CGFloat!
    let indicatorBottomMargin: CGFloat = 2
    let indicatorLeftMargin: CGFloat = 2
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        // setup tabbar indicator
        rectShape.fillColor = UIColor.redColor().CGColor
        indicatorWidth = view.bounds.maxX / 2 // count of items
        self.tabBarController!.view.layer.addSublayer(rectShape)
        self.tabBarController?.delegate = self
    
        // initial position
        updateTabbarIndicatorBySelectedTabIndex(0)
    }
    
    func updateTabbarIndicatorBySelectedTabIndex(index: Int) -> Void
    {
        let updatedBounds = CGRect( x: CGFloat(index) * (indicatorWidth + indicatorLeftMargin),
                                    y: view.bounds.maxY - indicatorHeight,
                                    width: indicatorWidth - indicatorLeftMargin,
                                    height: indicatorHeight)
    
        let path = CGPathCreateMutable()
        CGPathAddRect(path, nil, updatedBounds)
        rectShape.path = path
    }
    }
    
    extension FirstViewController: UITabBarControllerDelegate {
    
    func tabBarController(tabBarController: UITabBarController, didSelectViewController viewController: UIViewController) {
        updateTabbarIndicatorBySelectedTabIndex(tabBarController.selectedIndex)
    }
    }
    


来源:https://stackoverflow.com/questions/33667481/add-a-line-as-a-selection-indicator-to-a-uitabbaritem-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!