Mixin 0.1.2

Mixin 0.1.2

测试测试过
语言语言 SwiftSwift
许可 MIT
发布最后发布2017年12月
SwiftSwift 版本4.0
SPM支持 SPM

Howard Yang 维护。



Mixin 0.1.2

  • 编者
  • Howard Yang

Mixin🍹

Version
License
Platform

为什么?

Swift 是以协议为中心的编程语言,并且通过默认的协议扩展实现更强大。您可以为类添加 mixin 方法,就像 Ruby 的 Mixin。

但是,iOS 作为 UI 框架,像 UIViewController 这样的对象有自己的生命周期。如果您不能监听生命周期方法,mixin 作为扩展实际上并不能真正帮助。

例如,我编写了一个协议和扩展,用于监听键盘事件

protocol KeyboardMixin {
    var keyboardHeight: CGFloat? { set get }
    func registerKeyboard()
    func deregisterKeyboard()
}

extension KeyboardMixin {
    func registerKeyboard() {
        NotificationCenter.default.addObserver(forName: NSNotification.Name.UIKeyboardWillHide, object: nil, queue: nil) { [weak self] notification in
            self?.keyboardHeight = nil
        }
        NotificationCenter.default.addObserver(forName: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil, queue: nil) { [weak self] notification in
            if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
                self?.keyboardHeight = keyboardSize.height
            }
        }
    }
    func deregisterKeyboard() {
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
    }
}

但我仍然需要自己注册和注销

class ViewController: UIViewController, KeyboardMixin {
    var keyboardHeight: CGFloat? {
        didSet { }
    }
    override func viewWillAppear(_ animated: Bool) {
        registerKeyboard()
    }
    override func viewWillDisappear(_ animated: Bool) {
        deregisterKeyboard()
    }
}

问题是为什么我不能将某物 mixin 到现有的方法中,例如 UIViewController 的生命周期?

如果您编写过 React.js,您会发现它的 Mixin 机制非常有用。所以我只是将这个想法复制到 iOS 中。使用这个包后,您可以编写如下的 mixin。

public protocol KeyboardMixin: ViewControllerMixinable {
    var keyboardHeight: CGFloat? { set get }
}

public extension KeyboardMixin {
    private func registerKeyboard() {
        NotificationCenter.default.addObserver(forName: NSNotification.Name.UIKeyboardWillHide, object: nil, queue: nil) { [weak self] notification in
            self?.keyboardHeight = nil
        }
        NotificationCenter.default.addObserver(forName: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil, queue: nil) { [weak self] notification in
            if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
                self?.keyboardHeight = keyboardSize.height
            }
        }
    }
    private func deregisterKeyboard() {
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
    }
    fileprivate func viewWillAppear(_ animated: Bool) {
        registerKeyboard()
    }
    fileprivate func viewWillDisappear(_ animated: Bool) {
        deregisterKeyboard()
    }
}

并且可以像以下这样使用它

class ViewController: UIViewController, KeyboardMixin {
    var keyboardHeight: CGFloat? {
        didSet { }
    }
    override func viewWillAppear(_ animated: Bool) {
        // Don't worry, you can still do things here...
    }
}

简单到无法更简单!

它是如何工作的

此包使用 iOS 运行时来翻转方法,因此所有覆盖方法和 mixin 方法将同时被调用。

支持

此包支持 mixin 到

示例

查看示例 ViewController,它展示了如何使用 Mixin

要求

仅测试在 Swift 4

安装

Mixin 通过 CocoaPods 提供。要安装它,只需将以下行添加到您的 Podfile。

pod 'Mixin'

作者

Howard Yang,[email protected]

许可

Mixin 在 MIT 许可下可用。有关更多信息,请参阅 LICENSE 文件。