RxSwift의 example을 코드로 쓴다(그 1)
소개
코드에서만 RxSwift example을 다시 작성했습니다.
(레이아웃은 snapKit을 사용하고 있습니다)
example 그 1
TextFiled에 숫자를 넣으면 맨 아래 레이블에 세 개의 값의 합계가 즉시 계산되는 example
환경 구축
프로젝트 파일 만들기
이름은 무엇이든 좋지만 이번 예제에서는 RxSwift_for_code
podfile 편집
$ vi Podfile
Podfile의 내용target 'RxSwift_for_code' do
의 RxSwift_for_code
를 프로젝트 파일에서 사용한 이름으로 만드십시오.
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '9.0'
use_frameworks!
target 'RxSwift_for_code' do
pod 'RxSwift', '~> 4.0'
pod 'RxCocoa', '~> 4.0'
pod 'SnapKit', '~> 4.0.0'
end
Podfile에 등록한 라이브러리를 사용한다 (bundler로 cocoapod를 관리하고 있기 때문에 pod의 명령을 사용할 때는 bundle exec를 앞에 붙일 필요가 있다)
$ pod install
이 때 만든 RxSwift_for_code.xcworkspace를 시작합니다.
ViewController.swift
를 열고 아래 코드를 복사하여
코드 내용
ViewController.swiftのなかみ
import UIKit
import RxSwift
import RxCocoa
import SnapKit
class ViewController: UIViewController {
var disposeBag = DisposeBag()
var number1: UITextField = {
let textField = UITextField()
textField.borderStyle = .roundedRect
return textField
}()
var number2: UITextField = {
let textField = UITextField()
textField.borderStyle = .roundedRect
return textField
}()
var number3: UITextField = {
let textField = UITextField()
textField.borderStyle = .roundedRect
return textField
}()
var label: UILabel = {
let label = UILabel()
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(self.number1)
self.number1.snp.makeConstraints { (make) -> Void in
make.width.equalTo(200)
make.height.equalTo(50)
make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top).offset(100)
make.centerX.equalTo(self.view)
}
self.view.addSubview(self.number2)
self.number2.snp.makeConstraints { (make) -> Void in
make.width.equalTo(200)
make.height.equalTo(50)
make.top.equalTo(self.number1.snp.bottom)
make.centerX.equalTo(self.view)
}
self.view.addSubview(self.number3)
self.number3.snp.makeConstraints { (make) -> Void in
make.width.equalTo(200)
make.height.equalTo(50)
make.top.equalTo(self.number2.snp.bottom)
make.centerX.equalTo(self.view)
}
self.view.addSubview(self.label)
self.label.snp.makeConstraints { (make) -> Void in
make.width.equalTo(200)
make.height.equalTo(50)
make.top.equalTo(self.number3.snp.bottom)
make.centerX.equalTo(self.view)
}
//観測可能なシーケンスのいずれかが要素を生成するたびに、セレクタ関数を使用して、指定された観測可能なシーケンスを1つの観測可能なシーケンスにマージします。
//orEmpty:`String?`型のコントロールプロパティを `String`型のコントロールプロパティに変換します。
Observable.combineLatest(number1.rx.text.orEmpty,number2.rx.text.orEmpty,number3.rx.text.orEmpty) { textValue1, textValue2, textValue3 -> Int in
return (Int(textValue1) ?? 0) + (Int(textValue2) ?? 0) + (Int(textValue3) ?? 0)
}
//入ってきた値をStringに変換する関数
.map { $0.description}
//新しいサブスクリプションを作成し、オブザーバに要素を送信します。
.bind(to: label.rx.text)
.disposed(by: disposeBag)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
이해를 위한 나름대로의 해석
Observable에 이어지는 것은 처리의 일련의 흐름이라고 생각한다
CombineLatest라는 함수
이 함수는 관측하는 값(이 예라면 UITextFiled의 text의 값)을 복수 넣어 하나의 데이터의 흐름으로 하는 함수라고 생각한다
public static func combineLatest<O1, O2, O3>(_ source1: O1, _ source2: O2, _ source3: O3, resultSelector: @escaping (O1.E, O2.E, O3.E) throws -> Self.E) -> RxSwift.Observable<Self.E> where O1 : ObservableType, O2 : ObservableType, O3 : ObservableType
덧붙여서 위의 함수의 정의를 살펴보면 네 번째 인수인 resultSelector는 클로저를 받는 인수이다.
맨 마지막 인수로 클로저의 경우 위의 예와 같이 밖으로 튀어 나올 수 있습니다.
즉, 네 번째 인수는 이것입니다.
textValue1은 O1.E, textValue2는 O2.E, textValue3은 O3.E에 해당하는 도중에 String형은 Int로 변환되어 클로저 내의 처리가 끝난다(Self.E→Int가 되는군요)
{ textValue1, textValue2, textValue3 -> Int in
return (Int(textValue1) ?? 0) + (Int(textValue2) ?? 0) + (Int(textValue3) ?? 0)
}
number1.rx.text.orEmpty의 orEmpty
orEmpty: String?
형식의 컨트롤 속성을 String
형식의 컨트롤 속성으로 변환합니다.
UITextFiled에 들어가 있는지 들어 있지 않은지 모르는 값이기 때문에 String?이라는 것이 전제 조건이라고 생각하지만, 이 데이터의 흐름에 들어갈 때는 String형으로 변환해 주는 편리한 함수라고 하는 것 같다
$0.description
직전의 클로저의 처리를 빠져나가면 Int형의 데이터가 나오게 된다
map 함수는 흐르는 각 데이터를 처리하는 함수입니다.
클로저의 인수는 $ 0으로 표현 될 수 있으므로 클로저 내에서 Int로 변환 된 값 (예 : $ 0 = 14과 같은 값)이 들어옵니다.
$0.description과 같이 description을 연결하면 $0에 들어온 값을 String형으로 변환해준다
(예 14(Int)→"14"(String))
.bind(to: label.rx.text)
마지막으로 bind 함수에 들어가기
public func bind<O>(to observer: O) -> Disposable where O : ObserverType, O.E == Self.E?
인수는 observer 형의 무엇인가의 형태 반환값은 Disposable 로 들어오는 데이터와 같은 형태일 필요가 있다
String으로 변환한 값은, UILabel 클래스의 인스턴스인 label의 text에 넣는다고 하는 것 같다
.disposed(by: disposeBag)
마지막으로 흘러 들어간 앞의 값의 반환값은 전의 단계에서 Disposable가 되어 있을 것
이것은, 처리가 끝난 후에는 관측을 그만둘 필요가 있다고 하는 것으로 보지 않는 것처럼 붙이고 있는 감각
(언젠가 제대로 이해하면 쓰고 싶다)
Reference
이 문제에 관하여(RxSwift의 example을 코드로 쓴다(그 1)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/nakagawa1017/items/f894b1ac051fab08b95d
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
프로젝트 파일 만들기
이름은 무엇이든 좋지만 이번 예제에서는
RxSwift_for_code
podfile 편집
$ vi Podfile
Podfile의 내용
target 'RxSwift_for_code' do
의 RxSwift_for_code
를 프로젝트 파일에서 사용한 이름으로 만드십시오.source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '9.0'
use_frameworks!
target 'RxSwift_for_code' do
pod 'RxSwift', '~> 4.0'
pod 'RxCocoa', '~> 4.0'
pod 'SnapKit', '~> 4.0.0'
end
Podfile에 등록한 라이브러리를 사용한다 (bundler로 cocoapod를 관리하고 있기 때문에 pod의 명령을 사용할 때는 bundle exec를 앞에 붙일 필요가 있다)
$ pod install
이 때 만든 RxSwift_for_code.xcworkspace를 시작합니다.
ViewController.swift
를 열고 아래 코드를 복사하여코드 내용
ViewController.swiftのなかみ
import UIKit
import RxSwift
import RxCocoa
import SnapKit
class ViewController: UIViewController {
var disposeBag = DisposeBag()
var number1: UITextField = {
let textField = UITextField()
textField.borderStyle = .roundedRect
return textField
}()
var number2: UITextField = {
let textField = UITextField()
textField.borderStyle = .roundedRect
return textField
}()
var number3: UITextField = {
let textField = UITextField()
textField.borderStyle = .roundedRect
return textField
}()
var label: UILabel = {
let label = UILabel()
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(self.number1)
self.number1.snp.makeConstraints { (make) -> Void in
make.width.equalTo(200)
make.height.equalTo(50)
make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top).offset(100)
make.centerX.equalTo(self.view)
}
self.view.addSubview(self.number2)
self.number2.snp.makeConstraints { (make) -> Void in
make.width.equalTo(200)
make.height.equalTo(50)
make.top.equalTo(self.number1.snp.bottom)
make.centerX.equalTo(self.view)
}
self.view.addSubview(self.number3)
self.number3.snp.makeConstraints { (make) -> Void in
make.width.equalTo(200)
make.height.equalTo(50)
make.top.equalTo(self.number2.snp.bottom)
make.centerX.equalTo(self.view)
}
self.view.addSubview(self.label)
self.label.snp.makeConstraints { (make) -> Void in
make.width.equalTo(200)
make.height.equalTo(50)
make.top.equalTo(self.number3.snp.bottom)
make.centerX.equalTo(self.view)
}
//観測可能なシーケンスのいずれかが要素を生成するたびに、セレクタ関数を使用して、指定された観測可能なシーケンスを1つの観測可能なシーケンスにマージします。
//orEmpty:`String?`型のコントロールプロパティを `String`型のコントロールプロパティに変換します。
Observable.combineLatest(number1.rx.text.orEmpty,number2.rx.text.orEmpty,number3.rx.text.orEmpty) { textValue1, textValue2, textValue3 -> Int in
return (Int(textValue1) ?? 0) + (Int(textValue2) ?? 0) + (Int(textValue3) ?? 0)
}
//入ってきた値をStringに変換する関数
.map { $0.description}
//新しいサブスクリプションを作成し、オブザーバに要素を送信します。
.bind(to: label.rx.text)
.disposed(by: disposeBag)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
이해를 위한 나름대로의 해석
Observable에 이어지는 것은 처리의 일련의 흐름이라고 생각한다
CombineLatest라는 함수
이 함수는 관측하는 값(이 예라면 UITextFiled의 text의 값)을 복수 넣어 하나의 데이터의 흐름으로 하는 함수라고 생각한다
public static func combineLatest<O1, O2, O3>(_ source1: O1, _ source2: O2, _ source3: O3, resultSelector: @escaping (O1.E, O2.E, O3.E) throws -> Self.E) -> RxSwift.Observable<Self.E> where O1 : ObservableType, O2 : ObservableType, O3 : ObservableType
덧붙여서 위의 함수의 정의를 살펴보면 네 번째 인수인 resultSelector는 클로저를 받는 인수이다.
맨 마지막 인수로 클로저의 경우 위의 예와 같이 밖으로 튀어 나올 수 있습니다.
즉, 네 번째 인수는 이것입니다.
textValue1은 O1.E, textValue2는 O2.E, textValue3은 O3.E에 해당하는 도중에 String형은 Int로 변환되어 클로저 내의 처리가 끝난다(Self.E→Int가 되는군요)
{ textValue1, textValue2, textValue3 -> Int in
return (Int(textValue1) ?? 0) + (Int(textValue2) ?? 0) + (Int(textValue3) ?? 0)
}
number1.rx.text.orEmpty의 orEmpty
orEmpty: String?
형식의 컨트롤 속성을 String
형식의 컨트롤 속성으로 변환합니다.
UITextFiled에 들어가 있는지 들어 있지 않은지 모르는 값이기 때문에 String?이라는 것이 전제 조건이라고 생각하지만, 이 데이터의 흐름에 들어갈 때는 String형으로 변환해 주는 편리한 함수라고 하는 것 같다
$0.description
직전의 클로저의 처리를 빠져나가면 Int형의 데이터가 나오게 된다
map 함수는 흐르는 각 데이터를 처리하는 함수입니다.
클로저의 인수는 $ 0으로 표현 될 수 있으므로 클로저 내에서 Int로 변환 된 값 (예 : $ 0 = 14과 같은 값)이 들어옵니다.
$0.description과 같이 description을 연결하면 $0에 들어온 값을 String형으로 변환해준다
(예 14(Int)→"14"(String))
.bind(to: label.rx.text)
마지막으로 bind 함수에 들어가기
public func bind<O>(to observer: O) -> Disposable where O : ObserverType, O.E == Self.E?
인수는 observer 형의 무엇인가의 형태 반환값은 Disposable 로 들어오는 데이터와 같은 형태일 필요가 있다
String으로 변환한 값은, UILabel 클래스의 인스턴스인 label의 text에 넣는다고 하는 것 같다
.disposed(by: disposeBag)
마지막으로 흘러 들어간 앞의 값의 반환값은 전의 단계에서 Disposable가 되어 있을 것
이것은, 처리가 끝난 후에는 관측을 그만둘 필요가 있다고 하는 것으로 보지 않는 것처럼 붙이고 있는 감각
(언젠가 제대로 이해하면 쓰고 싶다)
Reference
이 문제에 관하여(RxSwift의 example을 코드로 쓴다(그 1)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/nakagawa1017/items/f894b1ac051fab08b95d
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
import UIKit
import RxSwift
import RxCocoa
import SnapKit
class ViewController: UIViewController {
var disposeBag = DisposeBag()
var number1: UITextField = {
let textField = UITextField()
textField.borderStyle = .roundedRect
return textField
}()
var number2: UITextField = {
let textField = UITextField()
textField.borderStyle = .roundedRect
return textField
}()
var number3: UITextField = {
let textField = UITextField()
textField.borderStyle = .roundedRect
return textField
}()
var label: UILabel = {
let label = UILabel()
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(self.number1)
self.number1.snp.makeConstraints { (make) -> Void in
make.width.equalTo(200)
make.height.equalTo(50)
make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top).offset(100)
make.centerX.equalTo(self.view)
}
self.view.addSubview(self.number2)
self.number2.snp.makeConstraints { (make) -> Void in
make.width.equalTo(200)
make.height.equalTo(50)
make.top.equalTo(self.number1.snp.bottom)
make.centerX.equalTo(self.view)
}
self.view.addSubview(self.number3)
self.number3.snp.makeConstraints { (make) -> Void in
make.width.equalTo(200)
make.height.equalTo(50)
make.top.equalTo(self.number2.snp.bottom)
make.centerX.equalTo(self.view)
}
self.view.addSubview(self.label)
self.label.snp.makeConstraints { (make) -> Void in
make.width.equalTo(200)
make.height.equalTo(50)
make.top.equalTo(self.number3.snp.bottom)
make.centerX.equalTo(self.view)
}
//観測可能なシーケンスのいずれかが要素を生成するたびに、セレクタ関数を使用して、指定された観測可能なシーケンスを1つの観測可能なシーケンスにマージします。
//orEmpty:`String?`型のコントロールプロパティを `String`型のコントロールプロパティに変換します。
Observable.combineLatest(number1.rx.text.orEmpty,number2.rx.text.orEmpty,number3.rx.text.orEmpty) { textValue1, textValue2, textValue3 -> Int in
return (Int(textValue1) ?? 0) + (Int(textValue2) ?? 0) + (Int(textValue3) ?? 0)
}
//入ってきた値をStringに変換する関数
.map { $0.description}
//新しいサブスクリプションを作成し、オブザーバに要素を送信します。
.bind(to: label.rx.text)
.disposed(by: disposeBag)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Observable에 이어지는 것은 처리의 일련의 흐름이라고 생각한다
CombineLatest라는 함수
이 함수는 관측하는 값(이 예라면 UITextFiled의 text의 값)을 복수 넣어 하나의 데이터의 흐름으로 하는 함수라고 생각한다
public static func combineLatest<O1, O2, O3>(_ source1: O1, _ source2: O2, _ source3: O3, resultSelector: @escaping (O1.E, O2.E, O3.E) throws -> Self.E) -> RxSwift.Observable<Self.E> where O1 : ObservableType, O2 : ObservableType, O3 : ObservableType
덧붙여서 위의 함수의 정의를 살펴보면 네 번째 인수인 resultSelector는 클로저를 받는 인수이다.
맨 마지막 인수로 클로저의 경우 위의 예와 같이 밖으로 튀어 나올 수 있습니다.
즉, 네 번째 인수는 이것입니다.
textValue1은 O1.E, textValue2는 O2.E, textValue3은 O3.E에 해당하는 도중에 String형은 Int로 변환되어 클로저 내의 처리가 끝난다(Self.E→Int가 되는군요)
{ textValue1, textValue2, textValue3 -> Int in
return (Int(textValue1) ?? 0) + (Int(textValue2) ?? 0) + (Int(textValue3) ?? 0)
}
number1.rx.text.orEmpty의 orEmpty
orEmpty:
String?
형식의 컨트롤 속성을 String
형식의 컨트롤 속성으로 변환합니다.UITextFiled에 들어가 있는지 들어 있지 않은지 모르는 값이기 때문에 String?이라는 것이 전제 조건이라고 생각하지만, 이 데이터의 흐름에 들어갈 때는 String형으로 변환해 주는 편리한 함수라고 하는 것 같다
$0.description
직전의 클로저의 처리를 빠져나가면 Int형의 데이터가 나오게 된다
map 함수는 흐르는 각 데이터를 처리하는 함수입니다.
클로저의 인수는 $ 0으로 표현 될 수 있으므로 클로저 내에서 Int로 변환 된 값 (예 : $ 0 = 14과 같은 값)이 들어옵니다.
$0.description과 같이 description을 연결하면 $0에 들어온 값을 String형으로 변환해준다
(예 14(Int)→"14"(String))
.bind(to: label.rx.text)
마지막으로 bind 함수에 들어가기
public func bind<O>(to observer: O) -> Disposable where O : ObserverType, O.E == Self.E?
인수는 observer 형의 무엇인가의 형태 반환값은 Disposable 로 들어오는 데이터와 같은 형태일 필요가 있다
String으로 변환한 값은, UILabel 클래스의 인스턴스인 label의 text에 넣는다고 하는 것 같다
.disposed(by: disposeBag)
마지막으로 흘러 들어간 앞의 값의 반환값은 전의 단계에서 Disposable가 되어 있을 것
이것은, 처리가 끝난 후에는 관측을 그만둘 필요가 있다고 하는 것으로 보지 않는 것처럼 붙이고 있는 감각
(언젠가 제대로 이해하면 쓰고 싶다)
Reference
이 문제에 관하여(RxSwift의 example을 코드로 쓴다(그 1)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/nakagawa1017/items/f894b1ac051fab08b95d텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)