“扩展不能包含存储的属性”阻止我重构代码

Jes*_*ble 5 refactoring swift coordinator-pattern

我有一个 13 行的 func,它在我的应用程序中的每个 ViewController 中重复,在整个项目中总共有 690 行代码!

/// Adds Menu Button
func addMenuButton() {
    let menuButton = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
    let menuImage = UIImage(named: "MenuWhite")
    menuButton.setImage(menuImage, for: .normal)

    menuButton.addTarget(self, action: #selector(menuTappedAction), for: .touchDown)
    self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: menuButton)
}
/// Launches the MenuViewController
@objc func menuTappedAction() {
    coordinator?.openMenu()
}
Run Code Online (Sandbox Code Playgroud)

要使 menuTappedAction 函数正常工作,我必须像这样声明一个弱变量:

extension UIViewController {

weak var coordinator: MainCoordinator?
Run Code Online (Sandbox Code Playgroud)

但是通过这样做,我得到了错误Extensions must not contain stored properties 到目前为止我尝试过的:

1)删除weak关键字将导致我所有应用程序中的冲突。2)这样声明:

weak var coordinator: MainCoordinator?
extension UIViewController {
Run Code Online (Sandbox Code Playgroud)

将消除错误,但协调器不会执行任何操作。任何建议如何解决这个问题?

Mus*_*les 6

为了使其在扩展中工作,您必须使其计算属性如下所示:-

extension ViewController {

   // Make it computed property
    weak var coordinator: MainCoordinator? {
        return MainCoordinator()
    }

}

Run Code Online (Sandbox Code Playgroud)


小智 6

您可以将addMenuButton()函数移动到带有协议扩展的协议。例如:

@objc protocol Coordinated: class {
    var coordinator: MainCoordinator? { get set }
    @objc func menuTappedAction()
}

extension Coordinated where Self: UIViewController {
    func addMenuButton() {
        let menuButton = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
        let menuImage = UIImage(named: "MenuWhite")
        menuButton.setImage(menuImage, for: .normal)

        menuButton.addTarget(self, action: #selector(menuTappedAction), for: .touchDown)
        self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: menuButton)
    }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,您不能@objc向类扩展添加方法(请参阅:this stackoverflow question),因此您仍然必须像这样设置视图控制器:

class SomeViewController: UIViewController, Coordinated {
    weak var coordinator: MainCoordinator?
    /// Launches the MenuViewController
    @objc func menuTappedAction() {
        coordinator?.openMenu()
    }
}
Run Code Online (Sandbox Code Playgroud)

它将为您节省一些代码,并允许您重构更大的函数addMenuButton()。希望这可以帮助!


Sh_*_*han 0

您可以通过子类化来做到这一点

class CustomVC:UIViewController {

    weak var coordinator: MainCoordinator?

    func addMenuButton() {
        let menuButton = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
        let menuImage = UIImage(named: "MenuWhite")
        menuButton.setImage(menuImage, for: .normal)

        menuButton.addTarget(self, action: #selector(menuTappedAction), for: .touchDown)
        self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: menuButton)
    }
    /// Launches the MenuViewController
    @objc func menuTappedAction() {
        coordinator?.openMenu()
    }

}

class MainCoordinator {

    func openMenu() {

    }
}


class ViewController: CustomVC {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

}
Run Code Online (Sandbox Code Playgroud)