어떤 셀에 여러 UI를 집어넣을때 top, left, right, bottom을 전부 오토레이아웃을 잡아놓으면 우리가 원치않게 UI들이 늘어나거나 하는 경우가 종종있다
그래서 어떤 UI를 만들때 sizeToFit과 left, top과 같이 일부분의 오토레이아웃만 잡아놓은 상태에서 보여주는걸 자주 하였다
우리가 어떤 UI에 대한 오토레이아웃을 걸때 항상 마지막에 건 UI는 딱 붙어있고 맨 처음 UI는 마지막 UI에 맞춰서 늘어진 형태를 볼 수 있을 것이다
이처럼 각각 UI에 priority를 매겨서 우선순위가 더 높은 UI를 늘어나게 하거나 줄어들게 할 수 있는 속성이라 생각하면 된다
case .location:
infoImageView.image = UIImage(named: "whiteLocation")
infoImageView.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
infoLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
그래서 위처럼 우선순위가 더 높은 이미지뷰가 오토레이아웃에 맞춰서 레이아웃을 조정하다가 여유간격이 나왔을때 먼저 좁아짐으로써 라벨에 대한 텍스트가 늘어나게끔 조절하였다
하지만 위와 같은 방법도 UI 구조상 틀린 코드는 아니지만 근본적인 문제였던 오바되는 문제를 해결하지는 못하였다
결국 셀을 침범하지못하기위해선 셀과 UI에 대한 오토레이아웃을 걸어줌으로써 침범하지못하게 하는 방법밖에 없었다
이런 상황에서 equalTo나 equalSuperView처럼 딱 고정시키는게 아닌 lessThan이라는 오토레이아웃코드를 발견하였다
categoryInfoListView.snp.makeConstraints {
$0.width.lessThanOrEqualTo(self.frame.width - 20)
}
Rx를 아예 안써본것은 아니지만 확실히 항상 써오던 코드는 대략 어떨때 사용하는지 감이 오지만 그 외의 코드들은 잘 감이 안온다
이번 PLUB이라는 프로젝트를 하면서 자주 사용하면서도 이번에 사용법에 대해 조금이나마 자세히 알게 된 Operator가 위 2개이다
내가 마주하게 된 상황은 셀을 단 하나라도 클릭했을 경우 floating Button이 enabled하게 모든 셀을 클릭하지않았을 경우에 unEnabled하게 변경하는 부분이였다
위와 같은 상황에서 클릭할때마다 카운트 수를 viewModel에 가지고있고 양수일땐 enabled true를 0일때 enabled false하게 구현하고 싶었다
selectingDetailCell.withLatestFrom(selectingDetailCellCount)
.map{ $0 + 1 }
.subscribe(onNext: selectingDetailCellCount.onNext(_:))
.disposed(by: disposeBag)
deselectingDetailCell.withLatestFrom(selectingDetailCellCount)
.map{ $0 - 1 }
.subscribe(onNext: selectingDetailCellCount.onNext(_:))
.disposed(by: disposeBag)
이 연산자는 동일한 방출값일때 무시하게 하는 아주 유용한 연산자 중 하나라고 생각한다
헌데 이번 프로젝트에서 기본 제공해주는 타입이 아닐 경우에 예를 들어 커스텀 구조체와 같은 데이터를 비교해야할 경우 직접 어떠한 경우에 무시할지를 코드해주어야한다
하지만 이번에 이 연산자에 대한 부분을 코드할때 Xcode에서 영문모를 오류투성이였고 나는 이를 편리하게 사용할 방법을 찾아내었다
struct QuestionStatus: Equatable {
let id: Int
let isFilled: Bool
static func == (lhs: QuestionStatus, rhs: QuestionStatus) -> Bool {
return lhs.id == rhs.id && lhs.isFilled == rhs.isFilled
}
}
entireQuestionStatus
.distinctUntilChanged()
.subscribe(onNext: { current in
let isAllChecked = current.filter{ $0.isFilled == false }.count == 0
isActivating.onNext(isAllChecked)
})
.disposed(by: disposeBag)
textField.rx.text
.subscribe(onNext: {
})
.disposed(by: disposeBag)
textView.rx.text
.subscribe(onNext: {
})
.disposed(by: disposeBag)
기본적으로 rx.text는 포커싱, 텍스트 입력, 언포커싱과 같이 다양한 이벤트들에 대해 반응하여 그 당시 UI의 텍스트에 대한 값을 내려보내준다
즉, editingChanged같은 실제 텍스트가 변할때만 값의 변동을 원하는 나의 경우 이에 맞지않았다
textField.rx.text
.orEmpty
.skip(1)
.distinctUntilChanged()
.filter { $0.count != 0 }