회사에서 시간이 남아서 리팩토링 할 코드가 뭐가 있을지 고민하던 중 이전에 들어본 FlexLayout, PinLayout에 대해 궁금증이 생겨서 찾아보게 되었다.(현재 진행하고 있는 기존 프로젝트들은 Snapkit, Then을 활용해 레이아웃을 구성하고 있다.)
FlexLayout과 PinLayout과 관련된 자료를 조사해보던 중 해당 라이브러리가 UIStackView 보다 8배에서 12배 더 빠르다는 장점이 있다는 것을 알게 되어 시간이 남는 김에 이를 적용해보고자 했다.
우선, 해당 코드는 자료 검색하고 한두시간 만에 만든 화면이라 이런식으로 레이아웃을 구성한 것이 맞는지는 모르겠다...
// Snapkit을 활용한 기존 코드
override func addViews() {
super.addViews()
view.addSubviews([descriptionStackView, confirmButton, cancelButton, deleteAccountButton])
descriptionStackView.addArrangedSubviews([firstDescriptionStackView,
secondDescriptionStackView,
thirdDescriptionStackView])
firstDescriptionStackView.addArrangedSubviews([firstNumberLabel, firstDescriptionLabel])
secondDescriptionStackView.addArrangedSubviews([secondNumberLabel, secondDescriptionLabel])
thirdDescriptionStackView.addArrangedSubviews([thirdNumberLabel, thirdDescriptionLabel])
confirmButton.addArrangedSubviews([checkImageView, confirmLabel])
}
override func makeConstraints() {
super.makeConstraints()
descriptionStackView.snp.makeConstraints {
$0.top.equalTo(titleLabel.snp.bottom).offset(moderateScale(number: 16))
$0.leading.trailing.equalToSuperview().inset(moderateScale(number: 20))
}
cancelButton.snp.makeConstraints {
$0.bottom.equalToSuperview().inset(getSafeAreaBottom() + moderateScale(number: 12))
$0.leading.equalToSuperview().inset(moderateScale(number: 20))
$0.width.equalTo(moderateScale(number: 127))
$0.height.equalTo(moderateScale(number: 52))
}
deleteAccountButton.snp.makeConstraints {
$0.leading.equalTo(cancelButton.snp.trailing).offset(moderateScale(number: 8))
$0.trailing.equalToSuperview().inset(moderateScale(number: 20))
$0.height.bottom.equalTo(cancelButton)
}
confirmButton.snp.makeConstraints {
$0.leading.trailing.equalToSuperview().inset(moderateScale(number: 20))
$0.bottom.equalTo(cancelButton.snp.top).offset(-moderateScale(number: 26))
}
checkImageView.snp.makeConstraints {
$0.size.equalTo(moderateScale(number: 20))
}
}
// FlexLayout, PinLayout을 활용한 코드
private func addViews() {
view.addSubview(containerView)
}
private func makeConstraints() {
containerView.flex.direction(.column)
.justifyContent(.spaceBetween)
.marginHorizontal(moderateScale(number: 20))
.define { flex in
flex.addItem().direction(.column).define { flex in
flex.addItem(topView).height(moderateScale(number: 40))
flex.addItem(titleLabel).marginTop(moderateScale(number: 8))
flex.addItem().direction(.row)
.marginTop(moderateScale(number: 40))
.marginBottom(moderateScale(number: 8))
.alignItems(.start)
.define { flex in
flex.addItem(firstNumberLabel)
flex.addItem(firstDescriptionLabel).marginLeft(moderateScale(number: 8))
}
flex.addItem().direction(.row)
.marginBottom(moderateScale(number: 8))
.alignItems(.start)
.define { flex in
flex.addItem(secondNumberLabel)
flex.addItem(secondDescriptionLabel).marginLeft(moderateScale(number: 8))
}
flex.addItem().direction(.row)
.alignItems(.start)
.define { flex in
flex.addItem(thirdNumberLabel)
flex.addItem(thirdDescriptionLabel).marginLeft(moderateScale(number: 8))
}
}
flex.addItem().direction(.column).define { flex in
flex.addItem().direction(.row)
.marginBottom(moderateScale(number: 37))
.define { flex in
flex.addItem(checkImageView)
flex.addItem(confirmLabel).marginLeft(moderateScale(number: 10))
}
flex.addItem().direction(.row)
.height(moderateScale(number: 52))
.define { flex in
flex.addItem(cancelButton).width(moderateScale(number: 127))
flex.addItem(deleteAccountButton).grow(1).marginLeft(moderateScale(number: 8))
}
}
}
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
containerView.pin.all(view.pin.safeArea)
containerView.flex.layout()
}
사용해보고 나서 느낀점은 예전에 사용해봤던 SwiftUI와 사용법이 비슷하다고 느꼈다.
물론 1년 넘게 snapkit을 활용했고, SwiftUI를 사용해본지도 거의 2년이 지나가서 당연히 지금은 더 불편하게 느껴졌지만, 사용법 측면에서는 SnapKit과 별 차이 없는 난이도..?라고 생각했다.
그리고 장점으로는 기존에 Snapkit을 활용하면서 모든 view를 StackView를 활용해 구현하는 스타일은 아니었다 보니 가끔 예상하지 못한 부분에서 view가 잘리는 현상이 종종 있었다. 그러나 FlexLayout, PinLayout은 StackView를 기반으로 작동하는 레이아웃(?)인 것 같아 보다 유연한 UI를 구현할 수 있겠다라는 생각이 들었다.
가독성 측면에서는 Snapkit보다 아주 조금..? 더 직관적이라는 생각은 들었다.(개인적인 생각)
그러나 무엇보다 성능상의 이점이 있기 때문에 적용할만한 메리트가 있다고 느껴졌다.
그리고 단점을 굳이 꼽자면 아직 메서드라던가 사용법을 잘 모른다는 점..? 인 것 같다.
이 부분은 시간을 투자하면 금방 익숙해질 것 같다는 생각이 들었다.
우선은 사수 분께 해당 기술 도입을 말씀드려보려 하는데 적용하게 된다면 새로운 기술을 사용할 수 있는 좋은 기회일 것 같다.
'iOS 개발 > UIKit' 카테고리의 다른 글
[UIKit]양쪽 cornerRadius가 다른 cell 구현 (2) | 2024.05.08 |
---|---|
[UIKit] custom TextField 만들기 (0) | 2023.08.03 |
회사에서 시간이 남아서 리팩토링 할 코드가 뭐가 있을지 고민하던 중 이전에 들어본 FlexLayout, PinLayout에 대해 궁금증이 생겨서 찾아보게 되었다.(현재 진행하고 있는 기존 프로젝트들은 Snapkit, Then을 활용해 레이아웃을 구성하고 있다.)
FlexLayout과 PinLayout과 관련된 자료를 조사해보던 중 해당 라이브러리가 UIStackView 보다 8배에서 12배 더 빠르다는 장점이 있다는 것을 알게 되어 시간이 남는 김에 이를 적용해보고자 했다.
우선, 해당 코드는 자료 검색하고 한두시간 만에 만든 화면이라 이런식으로 레이아웃을 구성한 것이 맞는지는 모르겠다...
// Snapkit을 활용한 기존 코드
override func addViews() {
super.addViews()
view.addSubviews([descriptionStackView, confirmButton, cancelButton, deleteAccountButton])
descriptionStackView.addArrangedSubviews([firstDescriptionStackView,
secondDescriptionStackView,
thirdDescriptionStackView])
firstDescriptionStackView.addArrangedSubviews([firstNumberLabel, firstDescriptionLabel])
secondDescriptionStackView.addArrangedSubviews([secondNumberLabel, secondDescriptionLabel])
thirdDescriptionStackView.addArrangedSubviews([thirdNumberLabel, thirdDescriptionLabel])
confirmButton.addArrangedSubviews([checkImageView, confirmLabel])
}
override func makeConstraints() {
super.makeConstraints()
descriptionStackView.snp.makeConstraints {
$0.top.equalTo(titleLabel.snp.bottom).offset(moderateScale(number: 16))
$0.leading.trailing.equalToSuperview().inset(moderateScale(number: 20))
}
cancelButton.snp.makeConstraints {
$0.bottom.equalToSuperview().inset(getSafeAreaBottom() + moderateScale(number: 12))
$0.leading.equalToSuperview().inset(moderateScale(number: 20))
$0.width.equalTo(moderateScale(number: 127))
$0.height.equalTo(moderateScale(number: 52))
}
deleteAccountButton.snp.makeConstraints {
$0.leading.equalTo(cancelButton.snp.trailing).offset(moderateScale(number: 8))
$0.trailing.equalToSuperview().inset(moderateScale(number: 20))
$0.height.bottom.equalTo(cancelButton)
}
confirmButton.snp.makeConstraints {
$0.leading.trailing.equalToSuperview().inset(moderateScale(number: 20))
$0.bottom.equalTo(cancelButton.snp.top).offset(-moderateScale(number: 26))
}
checkImageView.snp.makeConstraints {
$0.size.equalTo(moderateScale(number: 20))
}
}
// FlexLayout, PinLayout을 활용한 코드
private func addViews() {
view.addSubview(containerView)
}
private func makeConstraints() {
containerView.flex.direction(.column)
.justifyContent(.spaceBetween)
.marginHorizontal(moderateScale(number: 20))
.define { flex in
flex.addItem().direction(.column).define { flex in
flex.addItem(topView).height(moderateScale(number: 40))
flex.addItem(titleLabel).marginTop(moderateScale(number: 8))
flex.addItem().direction(.row)
.marginTop(moderateScale(number: 40))
.marginBottom(moderateScale(number: 8))
.alignItems(.start)
.define { flex in
flex.addItem(firstNumberLabel)
flex.addItem(firstDescriptionLabel).marginLeft(moderateScale(number: 8))
}
flex.addItem().direction(.row)
.marginBottom(moderateScale(number: 8))
.alignItems(.start)
.define { flex in
flex.addItem(secondNumberLabel)
flex.addItem(secondDescriptionLabel).marginLeft(moderateScale(number: 8))
}
flex.addItem().direction(.row)
.alignItems(.start)
.define { flex in
flex.addItem(thirdNumberLabel)
flex.addItem(thirdDescriptionLabel).marginLeft(moderateScale(number: 8))
}
}
flex.addItem().direction(.column).define { flex in
flex.addItem().direction(.row)
.marginBottom(moderateScale(number: 37))
.define { flex in
flex.addItem(checkImageView)
flex.addItem(confirmLabel).marginLeft(moderateScale(number: 10))
}
flex.addItem().direction(.row)
.height(moderateScale(number: 52))
.define { flex in
flex.addItem(cancelButton).width(moderateScale(number: 127))
flex.addItem(deleteAccountButton).grow(1).marginLeft(moderateScale(number: 8))
}
}
}
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
containerView.pin.all(view.pin.safeArea)
containerView.flex.layout()
}
사용해보고 나서 느낀점은 예전에 사용해봤던 SwiftUI와 사용법이 비슷하다고 느꼈다.
물론 1년 넘게 snapkit을 활용했고, SwiftUI를 사용해본지도 거의 2년이 지나가서 당연히 지금은 더 불편하게 느껴졌지만, 사용법 측면에서는 SnapKit과 별 차이 없는 난이도..?라고 생각했다.
그리고 장점으로는 기존에 Snapkit을 활용하면서 모든 view를 StackView를 활용해 구현하는 스타일은 아니었다 보니 가끔 예상하지 못한 부분에서 view가 잘리는 현상이 종종 있었다. 그러나 FlexLayout, PinLayout은 StackView를 기반으로 작동하는 레이아웃(?)인 것 같아 보다 유연한 UI를 구현할 수 있겠다라는 생각이 들었다.
가독성 측면에서는 Snapkit보다 아주 조금..? 더 직관적이라는 생각은 들었다.(개인적인 생각)
그러나 무엇보다 성능상의 이점이 있기 때문에 적용할만한 메리트가 있다고 느껴졌다.
그리고 단점을 굳이 꼽자면 아직 메서드라던가 사용법을 잘 모른다는 점..? 인 것 같다.
이 부분은 시간을 투자하면 금방 익숙해질 것 같다는 생각이 들었다.
우선은 사수 분께 해당 기술 도입을 말씀드려보려 하는데 적용하게 된다면 새로운 기술을 사용할 수 있는 좋은 기회일 것 같다.
'iOS 개발 > UIKit' 카테고리의 다른 글
[UIKit]양쪽 cornerRadius가 다른 cell 구현 (2) | 2024.05.08 |
---|---|
[UIKit] custom TextField 만들기 (0) | 2023.08.03 |