最好的方法来添加一个子视图多个UIViewControllers

时间:2018-08-01 09:14:22

标签: swift swift4

我正在尝试找到一种方法,将带有操作的简单UIButton子视图添加到某些UIViewControllers。

我认为它可以使用协议及其扩展名,但是扩展名does not allow是@objc方法,这意味着,我无法使用Selector添加目标。

我创建了另一个类来解决此@objc问题,但是我无法将视图添加为参数...

我还创建了一个UIViewController子类,并且可以正常工作,但是我不确定用该子类实现很多UIViewControllers是个好主意。

所以问题是,将具有操作的子视图添加到多个UIViewController的最佳解决方案是什么?

请参阅下面的代码:

public protocol ImplementNewRightIcon {
    func setupNewBottomRightMenu()
}

public extension ImplementNewRightIcon where Self: UIViewController {

func setupNewBottomRightMenu() {

    let buttonwith: CGFloat = 50

    let button: UIButton = {
       let btn = UIButton()
        btn.setImage(#imageLiteral(resourceName: "icons8-plus-math-50_white"), for: .normal)
        btn.backgroundColor = .red
        btn.clipsToBounds = true
        btn.layer.cornerRadius = buttonwith * 0.5
        btn.imageEdgeInsets = UIEdgeInsetsMake(10,10,10,10)
        btn.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.25).cgColor
        btn.layer.shadowOffset = CGSize(width: 0.0, height: 2.0)
        btn.layer.shadowOpacity = 0.5
        btn.layer.shadowRadius = 0.0
        btn.layer.masksToBounds = false
        btn.addTarget(SetupMenuLayer.sharedInstance, action: #selector(SetupMenuLayer.showMenuButtonDidTapped(SenderViewController:)), for: .touchUpInside)
        return btn;
    }()

    self.view.addSubview(button)
    button.anchor(top: nil, left: nil, bottom: self.view.bottomAnchor, right: self.view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 20, paddingRight: 20, width: buttonwith, height: buttonwith)

}

}

class SetupMenuLayer: NSObject {
static let sharedInstance = SetupMenuLayer()

@objc func showMenuButtonDidTapped(SenderViewController: UIViewController) {

    let bottomMenuView: UIView = {
        let view = UIView()
        view.backgroundColor = .red
        return view
    }()

    SenderViewController.view.addSubview(bottomMenuView)
    bottomMenuView.anchor(top: nil, left: SenderViewController.view.leftAnchor, bottom: SenderViewController.view.bottomAnchor, right: SenderViewController.view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: SenderViewController.view.frame.width, height: SenderViewController.view.frame.height / 3)

}

}

class ImplementNewRightIconView: UIViewController {

override func viewDidLoad() {
    self.setupNewRightIconBtn()
}

func setupNewRightIconBtn() {
    let buttonwith: CGFloat = 50

    let button: UIButton = {
        let btn = UIButton()
        btn.setImage(#imageLiteral(resourceName: "icons8-plus-math-50_white"), for: .normal)
        btn.backgroundColor = .red
        btn.clipsToBounds = true
        btn.layer.cornerRadius = buttonwith * 0.5
        btn.imageEdgeInsets = UIEdgeInsetsMake(10,10,10,10)
        btn.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.25).cgColor
        btn.layer.shadowOffset = CGSize(width: 0.0, height: 2.0)
        btn.layer.shadowOpacity = 0.5
        btn.layer.shadowRadius = 0.0
        btn.layer.masksToBounds = false
        //it works
        btn.addTarget(self, action: #selector(showMenuButtonDidTapped), for: .touchUpInside)
        return btn;
    }()

    self.view.addSubview(button)
    button.anchor(top: nil, left: nil, bottom: self.view.bottomAnchor, right: self.view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 20, paddingRight: 20, width: buttonwith, height: buttonwith)
}

@objc func showMenuButtonDidTapped() {

    let bottomMenuView: UIView = {
        let view = UIView()
        view.backgroundColor = .red
        return view
    }()

    self.view.addSubview(bottomMenuView)
    bottomMenuView.anchor(top: nil, left: self.view.leftAnchor, bottom: self.view.bottomAnchor, right: self.view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: self.view.frame.width, height: self.view.frame.height / 3)

}

}

3 个答案:

答案 0 :(得分:0)

如果您想在同一 ViewController 中添加多个UIViewControllers作为子视图,则肯定需要使用容器视图。

答案 1 :(得分:0)

您可以扩展UIButton并使用以下语义添加方法:

func addTergetClosure(didTouch: () -> Void)

didTouch将在touchUpInside事件中调用,详细说明here如何实现。 接下来,您只需要像以前一样对UIViewController制作一个具有Self约束的协议,这会将您的按钮添加为子视图。我将把button属性添加为协议的一部分,因为您可能需要在那些视图控制器中的某个位置访问它,不仅要添加将在touchUpInside上调用的button和closure。

所以会是这样:

protocol MyProtocol { 
   var button: UIButton { get set }
   func setButton()
}

extension MyProtocol where Self: UIViewController {
   func setButton() { ... }
}

如果您的按钮在ViewControllers上看起来相似,而不是我建议您使用静态字段将该逻辑分离到UIButton扩展,这将返回具有所需样式的UIButton。在提供的解决方案中,您只需在ViewController中设置按钮,如

class MyController: UIViewController, MyProtocol {
   var button = UIButton.shadowed
}

extension UIButton {
    static let shadowed: UIButton = { ... }
}

答案 2 :(得分:0)

如果要使多个视图控制器具有共享功能,或者在特定情况下,始终在同一位置添加此按钮,则应创建一个基本视图控制器以供其继承。

class ViewControllerWithMenu: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        setupNewBottomRightMenu()   
    }

    func setupNewBottomRightMenu() {

    let buttonwith: CGFloat = 50

    let button: UIButton = {
       let btn = UIButton()
        btn.setImage(#imageLiteral(resourceName: "icons8-plus-math-50_white"), for: .normal)
        btn.backgroundColor = .red
        btn.clipsToBounds = true
        btn.layer.cornerRadius = buttonwith * 0.5
        btn.imageEdgeInsets = UIEdgeInsetsMake(10,10,10,10)
        btn.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.25).cgColor
        btn.layer.shadowOffset = CGSize(width: 0.0, height: 2.0)
        btn.layer.shadowOpacity = 0.5
        btn.layer.shadowRadius = 0.0
        btn.layer.masksToBounds = false
        btn.addTarget(SetupMenuLayer.sharedInstance, action: #selector(SetupMenuLayer.showMenuButtonDidTapped(SenderViewController:)), for: .touchUpInside)
             return btn;
        }()

        self.view.addSubview(button)
        button.anchor(top: nil, left: nil, bottom: self.view.bottomAnchor, right: 
        self.view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 20, paddingRight: 20, width: buttonwith, height: buttonwith)

    }

}

现在您无需在每个视图控制器中调用任何东西,只需从此视图控制器而不是UIViewController扩展