测试测试过 | ✓ |
语言语言 | SwiftSwift |
许可 | MIT |
发布最后发布 | 2017年12月 |
SwiftSwift 版本 | 4.0 |
SPM支持 SPM | ✗ |
由 Howard Yang 维护。
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 文件。