代码之家  ›  专栏  ›  技术社区  ›  Roman

在Swift中使用布尔的视图控制器扩展

  •  0
  • Roman  · 技术社区  · 7 年前

    我正在尝试对视图控制器进行扩展。这是一个带有点击识别器的简单视图。如果按下一次,背景颜色应该从洋红色变为橙色。下一次推的时候,它应该又是洋红色了。

    import UIKit
    
    class StartVC: UIViewController {
        // bool
        var colorChanged = false
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            view.backgroundColor = UIColor.magenta
            setMyTouchableView2()
        }
    }
    
    extension StartVC {
        // make touchable view
        func setMyTouchableView2() {
            let myView = UIImageView(frame: CGRect(x: 100, y: 100, width: 50, height: 50))
            myView.backgroundColor = UIColor.yellow
    
            // add gesture recognizer
            let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(changeColor2(_:)))
            myView.addGestureRecognizer(tapGestureRecognizer)
            myView.isUserInteractionEnabled = true
    
            view.addSubview(myView)
        }
    
        func changeColor2(_ recognizer:UITapGestureRecognizer){
            if(colorChanged) {
                view.backgroundColor = UIColor.magenta
            } else {
                view.backgroundColor = UIColor.orange
            }
    
            colorChanged = !colorChanged
        }
    }
    

    但是,如果我尝试将此扩展推广到任何视图控制器,我会遇到以下问题:我无法将布尔值(colorChanged)放入视图控制器中,因为扩展将看不到它。我该怎么解决?

    代码如下:

    import UIKit
    
    class ViewController: UIViewController {
        // bool
        var colorChanged = false
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            view.backgroundColor = UIColor.magenta
            setMyTouchableView()
        }
    }
    
    extension UIViewController {
        // make touchable view
        func setMyTouchableView() {
            let myView = UIImageView(frame: CGRect(x: 100, y: 100, width: 50, height: 50))
            myView.backgroundColor = UIColor.yellow
    
            // add gesture recognizer
            let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(changeColor(_:)))
            myView.addGestureRecognizer(tapGestureRecognizer)
            myView.isUserInteractionEnabled = true
    
            view.addSubview(myView)
        }
    
        func changeColor(_ recognizer:UITapGestureRecognizer){
            if(colorChanged) {
                view.backgroundColor = UIColor.magenta
            } else {
                view.backgroundColor = UIColor.orange
            }
        }
    
    2 回复  |  直到 7 年前
        1
  •  2
  •   Victor Zaikin    7 年前

    默认情况下,扩展不能具有存储属性。但是,如果您真的需要它,您可以通过objc运行时创建它

    private var associationKey: UInt8 = 111 // Some constant
    
    extension ViewController {
        var colorChanged: Bool {
            get {
                return objc_getAssociatedObject(self, &associationKey) as! Bool
            }
            set {
                objc_setAssociatedObject(self, &associationKey, newValue, .OBJC_ASSOCIATION_ASSIGN)
            }
        }
    }
    

    protocol ColorChangable {
        var colorChange: Bool { get set }
    }
    
    extension ColorChangable where Self: UIViewController {
        func setMyTouchableView {
            // Your logic
        }
    }
    
    class ViewController: UIViewController {
        var colorChange: Bool
    
        func viewDidLoad() {
            self.viewDidLoad()
    
            setMyTouchableView()
        }
    }
    
    extension ViewController: ColorChangable {}
    
        2
  •  0
  •   Jack    7 年前

    可以使用struct生成全局变量-

       struct GlobalStruct {
        static var colorChanged = false
    }
    
    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            view.backgroundColor = UIColor.magenta
            setMyTouchableView()
        }
    }
    
    extension UIViewController {
        // make touchable view
        func setMyTouchableView() {
            let myView = UIImageView(frame: CGRect(x: 100, y: 100, width: 50, height: 50))
            myView.backgroundColor = UIColor.yellow
    
            // add gesture recognizer
            let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(changeColor(_:)))
            myView.addGestureRecognizer(tapGestureRecognizer)
            myView.isUserInteractionEnabled = true
    
            view.addSubview(myView)
        }
    
        func changeColor(_ recognizer:UITapGestureRecognizer){
            if(GlobalStruct.colorChanged) {
                view.backgroundColor = UIColor.magenta
            } else {
                view.backgroundColor = UIColor.orange
            }
        }
    }