【问题标题】:Swift 3: How to have a "global" button and action used in multiple controllersSwift 3:如何在多个控制器中使用“全局”按钮和操作
【发布时间】:2016-12-05 17:49:21
【问题描述】:

假设我有 20 个视图控制器都需要相同的按钮和操作,有没有办法避免在每个控制器中实现相同的 ibaction?我是否应该使用我的操作将 UIViewController 子类化,然后将我的控制器基于该子类?还是有其他方法?

【问题讨论】:

    标签: swift uiviewcontroller swift3


    【解决方案1】:

    我最终遵循了此处概述的基于协议/价值的方法 -> subclassing-can-suck-and-heres-why

    就我而言,我有一个位于多个视图上的“设置”按钮。

    protocol SettingsButtonRenderer {
        func goToSettings()
    }
    
    extension SettingsButtonRenderer where Self: UIViewController {
        func goToSettings() {
            let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
            let settingsNavigationController = storyBoard.instantiateViewController(withIdentifier: "SettingsNavigationController")
            present(settingsNavigationController, animated: true, completion: nil)
         }
    }
    
    class DeliveryTabViewController: UIViewController, SettingsButtonRenderer {
    
        @IBOutlet weak var goToSettingBtn: UIBarButtonItem!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            goToSettingBtn.target = self
            goToSettingBtn.action = #selector(DeliveryTabViewController.settingsClicked as (DeliveryTabViewController) -> () -> ())
        }
    
        func settingsClicked() {
            goToSettings()
        }
    }
    

    【讨论】:

      【解决方案2】:

      你可以继承 UIButton 并创建一个便利的初始化器。

      public class CloseButton: UIButton {
          convenience init(
              tag     :Int,
              target  :Any,
              action  :Selector
              )
          {
              self.init(frame: CGRect.zero)
              self.backgroundColor = UIColor.red
              self.setTitle("Close", for: .normal)
              self.tintColor = UIColor.white
              self.layer.cornerRadius = 5
              self.layer.borderColor = UIColor.white.cgColor
              self.layer.borderWidth = 1
              self.tag = tag
              self.addTarget(target, action: action, for: .touchUpInside)
          }
      }
      
      • 我在代码中连同我的 AutoLayout 一起编写了这种东西,这就是 CGRect.zero 帧的原因。
      • 您可以将目标/选择器设为可选。我以前是这样的,但这只是我使用的代码。
      • 也可以使便利的 init() 失效。自行配置!
      • 有些东西可能无法在 IB 中设置,但大多数可以通过添加 @IBDesignable/@IBInspectable 来实现。

      【讨论】:

        【解决方案3】:

        不确定您所说的“全局”按钮是什么意思。但是,如果我有一个调用 function 的按钮,该按钮通常在多个视图控制器中重复使用,我通常会根据适当的情况为 function 创建一个 protocolhelper 对象。

        但是,如果您的“全局”按钮指的是位于同一位置的按钮floating,而不管用户在哪个ViewController,那么我认为您可以看看这个。 https://github.com/yoavlt/LiquidFloatingActionButton

        这是一个浮动按钮,类似于 Google Mail 应用程序中的按钮。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-02-26
          • 2017-03-06
          • 1970-01-01
          相关资源
          最近更新 更多