在 Swift 中向 UITabbarItem 添加一行作为选择指示器
Add a line as a selection indicator to a UITabbarItem in Swift
我想在 UITabbarItems 的底部使用粗线作为选择指示器。由于该应用程序必须在不同的 phone 大小上运行,我不能使用图像作为选择指示器。这就是为什么我认为我必须使用 Swift 来执行此操作。 (线必须是页面宽度的 1/3)。
我尝试使用 UITabBarItem.appearance()
但没有成功。
您可以通过添加将在您的代码中创建的自定义图像到 UITabBar
对象上的 selectionIndicatorImage
来实现。例如,您可以像这样为 UIImage
class 创建 extension
:
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
}
}
然后在你第一次加载时调用它 ViewController
像这样:
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.
}
}
在这种情况下,结果将是这样的:
我解决了我的问题。
这个小代码片段的特点:
- 宽度是动态的
- 它是动画的
未来功能的可定制性要高得多
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)
}
}
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)
}
Swift 4.x
Xcode10.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!
}
}
使用
tabBar.selectionIndicatorImage = UIImage().createSelectionIndicator(color: BLUE, size: CGSize(width: tabBar.frame.width/CGFloat(tabBar.items!.count), height: tabBar.frame.height), lineWidth: 2.0)
我想在 UITabbarItems 的底部使用粗线作为选择指示器。由于该应用程序必须在不同的 phone 大小上运行,我不能使用图像作为选择指示器。这就是为什么我认为我必须使用 Swift 来执行此操作。 (线必须是页面宽度的 1/3)。
我尝试使用 UITabBarItem.appearance()
但没有成功。
您可以通过添加将在您的代码中创建的自定义图像到 UITabBar
对象上的 selectionIndicatorImage
来实现。例如,您可以像这样为 UIImage
class 创建 extension
:
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
}
}
然后在你第一次加载时调用它 ViewController
像这样:
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.
}
}
在这种情况下,结果将是这样的:
我解决了我的问题。
这个小代码片段的特点:
- 宽度是动态的
- 它是动画的
未来功能的可定制性要高得多
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) } }
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)
}
Swift 4.x
Xcode10.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!
}
}
使用
tabBar.selectionIndicatorImage = UIImage().createSelectionIndicator(color: BLUE, size: CGSize(width: tabBar.frame.width/CGFloat(tabBar.items!.count), height: tabBar.frame.height), lineWidth: 2.0)