【问题标题】:Add a line as a selection indicator to a UITabbarItem in Swift在 Swift 中将一行作为选择指示器添加到 UITabbarItem
【发布时间】:2016-02-13 13:02:41
【问题描述】:

我想在 UITabbarItems 底部使用粗线作为选择指示器。由于该应用程序必须在不同的手机尺寸上运行,我不能使用图像作为选择指标。这就是为什么我认为我必须使用 Swift 来做到这一点。 (该行必须是页面宽度的 1/3)。

我尝试使用UITabBarItem.appearance(),但没有成功。

【问题讨论】:

  • 您可以使用UIView 并将选定的背景颜色设置为相同。

标签: swift uitabbar uitabbaritem


【解决方案1】:

斯威夫特 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!
    }
}

使用

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

【讨论】:

    【解决方案2】:

    斯威夫特 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)
    }
    

    【讨论】:

    • 谢谢,但在 iphone X 11.2 中,这不起作用,意味着 2.0px 条与 tarbar 不对齐,它向下 20pix。有什么想法吗?
    • @SureshDurishetti 在 willlayoutSubviews 函数中调用你的函数,它会很好用
    【解决方案3】:

    您可以通过将在您的代码中创建的自定义图像添加到您的UITabBar 对象上的selectionIndicatorImage 来做到这一点。例如,您可以像这样为UIImage 类创建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.
        }
    }
    

    在这种情况下,结果将是这样的:

    【讨论】:

    • 不错的解决方案,但您的扩展确实应该是一个类函数,目前您正在初始化两个UIImages。
    【解决方案4】:

    我解决了我的问题。

    这个小代码sn-p的特点:

    • 宽度是动态的
    • 它是动画的
    • 它可以为未来的功能定制更多

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

    【讨论】:

    • 不错的解决方案。你试过这个吗?我的意思是当我运行这段代码时,它适用于第一个选项卡。单击第二个选项卡后,指示器显示选项卡栏的上侧。
    • 你应该使用view.bounds.maxY而不是(tabBarController?.view.bounds.maxY)!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-10
    • 1970-01-01
    相关资源
    最近更新 更多