티스토리 뷰

728x90
반응형



R슬라이더, G슬라이더, B슬라이더가 있고 RGB값에 따라 해당 색깔이 나오는 colorview를 만들어주자 :) 


스토리보드에서 슬라이더와 뷰를 뷰컨트롤러에 올려주고 슬라이더의 min값은 0, max값은 1로 설정해주기! 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import UIKit
import RxCocoa
import RxSwift
 
class ColorViewController: UIViewController {
    
    @IBOutlet weak var colorView: UIView!
    @IBOutlet weak var rLabel: UILabel!
    @IBOutlet weak var gLabel: UILabel!
    @IBOutlet weak var bLabel: UILabel!
    @IBOutlet weak var rSlider: UISlider!
    @IBOutlet weak var gSlider: UISlider!
    @IBOutlet weak var bSlider: UISlider!
    
    var disposeBag = DisposeBag()
    override func viewDidLoad() {
        super.viewDidLoad()
        bind()
    }
}
 
extension ColorViewController{
    
    func bind(){
        
        // 1) 각각의 slider에 대한 observable을 만들어서 관찰하자!
        let rObservable = rSlider.rx.value.map { CGFloat($0) }
        let gObservable = gSlider.rx.value.map { CGFloat($0) }
        let bObservable = bSlider.rx.value.map { CGFloat($0) }
        
        // 2) 255를 곱해서 rgb값으로 만들어주고 string으로 바꿔서 각각의 label에 바인딩 해주자
        rObservable.map{ "\(Int($0*255))" }
        .bind(to: rLabel.rx.text)
        .disposed(by: disposeBag)
        
        gObservable.map { "\(Int($0 * 255))"}
        .bind(to: gLabel.rx.text)
        .disposed(by: disposeBag)
        
        bObservable.map { "\(Int($0 * 255))"}
        .bind(to: bLabel.rx.text)
        .disposed(by: disposeBag)
        
        // 3) rgb값으로 view의 색을 변경해주자
        // combinelatest연산자 활용
        let color = Observable<UIColor>.combineLatest(rObservable, gObservable, bObservable) { (rValue, gValue, bValue) -> UIColor in
            return UIColor(red: rValue, green: gValue, blue: bValue, alpha: 1)
        }
        
 
        color.subscribe(onNext: { [weak self] (color) in
            self?.colorView.backgroundColor = color
        }).disposed(by: disposeBag)
        
    }
}
 
cs



위의 코드처럼 Observable<UIColor>를 subscribe하는 것이 아니라 바로 바인딩 해주고 싶다면 extension을 활용할 수 있다 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import UIKit
import RxCocoa
import RxSwift
 
class ColorViewController: UIViewController {
    
    @IBOutlet weak var colorView: UIView!
    @IBOutlet weak var rLabel: UILabel!
    @IBOutlet weak var gLabel: UILabel!
    @IBOutlet weak var bLabel: UILabel!
    @IBOutlet weak var rSlider: UISlider!
    @IBOutlet weak var gSlider: UISlider!
    @IBOutlet weak var bSlider: UISlider!
    
    var disposeBag = DisposeBag()
 
    override func viewDidLoad() {
        super.viewDidLoad()
        bind()
    }
 
}
 
extension ColorViewController{
    
    func bind(){
        
        // 1) 각각의 slider에 대한 observable을 만들어서 관찰하자!
        let rObservable = rSlider.rx.value.map { CGFloat($0) }
        let gObservable = gSlider.rx.value.map { CGFloat($0) }
        let bObservable = bSlider.rx.value.map { CGFloat($0) }
        
        // 2) 255를 곱해서 rgb값으로 만들어주고 string으로 바꿔서 각각의 label에 바인딩 해주자
        rObservable.map{ "\(Int($0*255))" }
        .bind(to: rLabel.rx.text)
        .disposed(by: disposeBag)
        
        gObservable.map { "\(Int($0 * 255))"}
        .bind(to: gLabel.rx.text)
        .disposed(by: disposeBag)
        
        bObservable.map { "\(Int($0 * 255))"}
        .bind(to: bLabel.rx.text)
        .disposed(by: disposeBag)
        
        // 3) rgb값으로 view의 색을 변경해주자
        // combinelatest연산자 활용
        let color = Observable<UIColor>.combineLatest(rObservable, gObservable, bObservable) { (rValue, gValue, bValue) -> UIColor in
            return UIColor(red: rValue, green: gValue, blue: bValue, alpha: 1)
        }
 
        // extension을 했기 때문에 UIView.rx에 backgroundColor속성을 사용할 수 있다. 
        color.bind(to: colorView.rx.backgroundColor)
        .disposed(by: disposeBag)
        
    }
}
 
extension Reactive where Base:UIView{
    var backgroundColor:Binder<UIColor>{
 
        return Binder(self.base,binding:{ (view,color) in
            view.backgroundColor = color
        })
        
        /* 또는 후행클로저로도 할 수 있다
         return Binder(self.base){ view,color in
         view.backgroundColor = color
         }
         */
    }
}
 
cs




combinelatest 연산자에 관한 것은 다음 사이트를 참조하기! 

http://reactivex.io/documentation/ko/operators/combinelatest.html

반응형
댓글