【问题标题】:Adding float action button to a view controller inside tab bar controller将浮动操作按钮添加到选项卡栏控制器内的视图控制器
【发布时间】:2018-10-22 12:59:24
【问题描述】:

我正在使用一个自定义浮动操作按钮 (Floaty),我想以编程方式将其添加到位于 UITabBarController 内的 UITableViewController。问题是底部标签栏覆盖在浮动操作按钮的顶部。

在我的表格视图控制器中:

let floaty = Floaty()
...
self.view.addSubview(floaty)
// also tried: self.tabBarController?.view.addSubview(floaty)

我尝试像这样设置边距:

floaty.layoutMargins = UIEdgeInsets(top: 0, left: 0, bottom: 60, right: 0)
floaty.layoutIfNeeded()
self.view.layoutIfNeeded()

但它不起作用。

如何在表格视图控制器中正确放置按钮?或者至少,如何以编程方式设置下边距?

编辑:

也试过了

self.navigationController?.view.addSubview(floaty)

起初它会正确添加按钮,但是当我切换选项卡时,它会恢复到底部栏覆盖的位置。 这里:

【问题讨论】:

  • Floaty 是否定位自身,或者是否还有更多您未在此处显示的代码将按钮置于屏幕右下角?
  • 是的,它把自己定位在底角

标签: ios swift uitabbarcontroller floating-action-button


【解决方案1】:

这行代码将解决填充问题:

floaty.paddingY += tabBarController!.tabBar.frame.size.height

如果您希望晶圆厂对您的所有标签都是全局的,您应该在此处添加它:

tabBarController!.view.addSubview(floaty)

否则,如果您将它添加到 navigationController 并且我假设您对每个选项卡都有一个不同的选项卡,那么它将仅存在于该 navigationController 的 viewControllers 中。如果将它添加到 self.view 中也会发生同样的情况,因为它只会存在于该视图控制器中。

另外,如果您想在某些特定的视图控制器中隐藏/取消隐藏 fab,您应该使用viewWillAppear/viewDidAppear/viewWillDisappear/viewDidDisappear 方法的组合,如下所示:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    floaty.isHidden = false
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    floaty.isHidden = true
}

祝你好运!

【讨论】:

    【解决方案2】:

    你不应该在你的 tableView 中实现它, 你应该把它添加到你已经实现你的标签的你的 homeTabs 您既不能通过添加为 IBOutlet 来添加它,也不能只是将其声明为按钮 这是我的代码(我的竞赛标签中有一个浮动按钮)

      @IBOutlet weak var leaderBoardBtn: UIButton!
    

    //为你的按钮添加bottom-top-leading-trailing约束

      @IBOutlet weak var leadBottom: NSLayoutConstraint!  
    

    ///这会导致我的按钮浮动 // 这是我的按钮底部对 superView.bottom 的约束

    然后在 viewDidLoad 中:

      NotificationCenter.default.addObserver(self, selector: #selector(leadAnime(_:)),name:NSNotification.Name(rawValue: "animate"), object: nil)
    

    然后在 viewDidLoad 之外的地方添加这个:

    @objc func leadAnime(_ notification: NSNotification) {
            if let  count = notification.userInfo?["top"] as? Bool{
                if count{
                    leadBottom.constant = 20
                    UIView.animate(withDuration: 0.3, animations: {
                        self.view.layoutIfNeeded()
                    })
                }else{
                    leadBottom.constant = -100
                    UIView.animate(withDuration: 0.3, animations: {
                        self.view.layoutIfNeeded()
                    })
                }
    
            }
        }
    

    现在在你的表格视图控制器中:

     var scrollS :CGFloat = 0
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "animate"), object: nil, userInfo: ["top":false])
    
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
         NotificationCenter.default.post(name: NSNotification.Name(rawValue: "animate"), object: nil, userInfo: ["top":true]) }
    
       override func scrollViewDidScroll(_ scrollView: UIScrollView) {
            if scrollS - scrollView.contentOffset.y < 0{
                NotificationCenter.default.post(name: NSNotification.Name(rawValue: "animate"), object: nil, userInfo: ["top":true])
            }else{
                if scrollS - scrollView.contentOffset.y > 0{
                    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "animate"), object: nil, userInfo: ["top":false])
                }
            }
            scrollS = scrollView.contentOffset.y
    
        }
        override func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
            if scrollS - scrollView.contentOffset.y < 0{
                NotificationCenter.default.post(name: NSNotification.Name(rawValue: "animate"), object: nil, userInfo: ["top":true])
            }else{
                if scrollS - scrollView.contentOffset.y > 0{
                    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "animate"), object: nil, userInfo: ["top":false])
                }
            }
            scrollS = scrollView.contentOffset.y
        }
    

    【讨论】:

    • 这是针对任何视图的通用解决方案,还是您明确指的是 Floaty?
    • 是的,这是一个通用的解决方案,因为它是在更新约束的基础上工作的
    【解决方案3】:

    您在 标签栏控制器下方的视图控制器上添加了按钮:

    self.view.addSubview(floaty)
    

    当然,标签栏将始终位于您将按钮添加为子视图的视图控制器上方。 看图2UITabBarController documentation

    【讨论】:

      【解决方案4】:

      2020 年使用 Swift 5 修复位置的解决方案在 iPhoneX 上不正确(具有安全区域视图):

      var floaty: Floaty!
      var shouldLayoutFloaty = false
      
      override func viewDidLoad() {
          super.viewDidLoad()
          initFloaty()
      }
      
      func initFloaty() {
        ...do something with Floaty
      
        shouldLayoutFloaty = true
      }
      
      override func viewDidLayoutSubviews() {
              super.viewDidLayoutSubviews()
      
              if shouldLayoutFloaty { // use this check to prevent infinite loop of "viewDidLayoutSubviews"
                  // call "tabBar.frame.size.height" in "viewDidLayoutSubviews" will return the exact height of tab bar on iPhoneX
                  floaty.paddingY = tabBar.frame.size.height + 20
                  shouldLayoutFloaty = false
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-24
        • 2017-11-15
        相关资源
        最近更新 更多