简体   繁体   中英

Property Observer for color change in swift

I've successfully created a simple iOS app that will change the background color When I click on the button. But. now the problem is I've no idea on how to implement property observer to print out message to the effect of the color whenever the color has changed.

UIColorExtension.swift

 import UIKit
 extension UIColor {

      static var random: UIColor {
        // Seed (only once)
        srand48(Int(arc4random()))
        return UIColor(red: CGFloat(drand48()), green: CGFloat(drand48()), blue: CGFloat(drand48()), alpha: 1.0)
      }
 }

ViewController.Swift

 import UIKit

 class ViewController: UIViewController {

      override func viewDidLoad() {
           super.viewDidLoad()

           // apply random color on view did load
           applyRandomColor()
       }


       @IBAction func btnHandler(_ sender: Any) {

           // on each button click, apply random color to view
           applyRandomColor()
       }

       func applyRandomColor() {
           view.backgroundColor = UIColor.random
       }
}

Please teach me on how to use property observer to monitor and print the color each time the color is changed as I don't have the slightest idea to do so.

At the moment you're just doing this

 view.backgroundColor = X

instead, you probably want to make your own "property"....

 var mood: UIColor { }

properties can have a "didSet" action...

 var mood: UIColor {
    didSet {
       view.backgroundColor = mood
       print("Hello!")
    }
 }

So now, just use "mood" when you want to change the background color.

mood = X

But, you can ALSO run any other code - where it prints the Hello.

Imagine your program has 100s of places where you do this thing of changing the background color .

If you use a property, you can change what happens "all at once" by just changing the code at print("Hello").

Otherwise, you'd have to change every one of the 100s of places where you do that.

This is a real basic in programming. Enjoy!

If you really need an observer Swift 4 provides a very smart way to do that:

  • Declare a NSKeyValueObservation property

     var observation : NSKeyValueObservation? 
  • In viewDidLoad add the observer, the closure is executed whenever the background color changes.

     observation = observe(\\.view.backgroundColor, options: [.new]) { _, change in print(change.newValue!) } 

In Swift there are two types of property observers ie:

willSet

didSet

You can find it in the Swift documentation here .

if you just need to print color description using property observer then you can create property and set its observers like this:

var backgroundColor = UIColor() {
    didSet {
        print("didSet value : \(backgroundColor)")
    }
}

and your complete code will look like:

import UIKit

class ViewController: UIViewController {

    var backgroundColor = UIColor() {
        didSet {
            print("didSet value : \(backgroundColor)")
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        self.applyRandomColor()
    }

    @IBAction func btnHandler(_ sender: Any) {

        // on each button click, apply random color to view
        applyRandomColor()

    }

    func applyRandomColor() {
        backgroundColor = UIColor.random
        self.view.backgroundColor = backgroundColor

    }


}

extension UIColor {

    static var random: UIColor {
        // Seed (only once)
        srand48(Int(arc4random()))
        return UIColor(red: CGFloat(drand48()), green: CGFloat(drand48()), blue:
            CGFloat(drand48()), alpha: 1.0)
    }
}

First of all you don't need any observer here because you know when the color is changing as it is changing by you manually by calling the applyRandomColor() function. So you can do here whatever you want to do.

After that if you still want to see how observer works. Then add an observer in class where you want to observe this event.

view.addObserver(self, forKeyPath: "backgroundColor", options: NSKeyValueObservingOptions.new, context: nil)

And here is the event:

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
      if keyPath == "backgroundColor" {
          /// Background color has changed
          /// Your view which backgroundColor it is
          guard let view = object as? UIView else {return}
          print(view.backgroundColor)
                    OR
          guard let color = change?[.newKey] as? UIColor else {return}
          print(color)
      }
}

First add observer like this:

view.addObserver(self, forKeyPath: "backgroundColor", options: [.new], context: nil)

Then override the function:

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    guard let color = change?[.newKey] as? UIColor else {return}
    print(color)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM