Swift 3 - full width of UITabBarItem for selection

2019-03-03 11:31发布

问题:

i have a UITabBar with three tabs. Now I want to assign or lets say to fill the complete width of one tab to the related selectionIndicatorImage cause currently I got a border if a tab is selected. Like the tab on the left side shows in the following screenshot:

I made a subclass of UITabBar with a new property:

var activeItemBackground:UIColor = UIColor.white {
    didSet {

        let numberOfItems = CGFloat((items!.count))

        let tabBarItemSize = CGSize(width: frame.width / numberOfItems,
                                    height: frame.height)

        selectionIndicatorImage = UIImage.imageWithColor(color: activeItemBackground,
                                     size: tabBarItemSize).resizableImage(withCapInsets: .zero)

        frame.size.width = frame.width + 4
        frame.origin.x = -2


    }
}

And the UIImage-Extension in order to have backgroundColor and an image:

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

I read much stuff about this problem but unfortunately I can't get it to work. Is something missing in my code?

回答1:

I think you're taking a couple extra steps...

You are calculating the exact size of the tab bar item, and creating an image of that size, so you shouldn't need the .resizableImage part.

And, since you are setting to exact size, you also shouldn't need to resize the tab bar frame.

This appears to work fine in my testing (using your .imageWithColor func):

class MyTabBar: UITabBar {

    var activeItemBackground:UIColor = UIColor.white {
        didSet {

            let numberOfItems = CGFloat((items!.count))

            let tabBarItemSize = CGSize(width: frame.width / numberOfItems,
                                        height: frame.height)

            selectionIndicatorImage = UIImage.imageWithColor(color: activeItemBackground,
                                                             size: tabBarItemSize)

        }
    }

}

Then in viewDidLoad of the first VC:

    if let tb = self.tabBarController?.tabBar as? MyTabBar {
        tb.activeItemBackground = UIColor.red
    }