티스토리 뷰
안녕하세요 :) Zedd입니다.
오늘은 PinLayout 사용해보기에 이어서..PinLayout의 친구인 FlexLayout에 대해서 공부해보겠습니다!
# FlexLayout
- UIStackView를 개선한 Layout 프레임워크
- UIStackView보다 사용하기 간단 / 다양한 API
- 높은 성능 → UIStackViews보다 8 ~ 12배 빠름.
- PinLayout과 같이 개발되었으므로 PinLayout과 유사한 구문과 메소드.
- 보통 PinLayout과 같이 사용된다.
# PinLayout과의 차이점?
PinLayout도 Layout 프레임워크였는데..FlexLayout는 뭐가 다르냐!
많은 View를 레이아웃 해야 하지만, 복잡한 애니메이션이 필요하지 않은 상황에서는 FlexLayout이 적합하다.
# 설치
installation 참고
# 사용해보기
FlexLayout를 사용하는 단계는 2단계로 나뉘어짐.
1. Container를 setup한다.
2. Container를 Layout한다.
1. Container를 setup한다.
import FlexLayout
let rootFlexContainer: UIView = UIView()
init() {
self.view.addSubView(self.rootFlexContainer)
self.rootFlexContainer.flex.define { (flex) in
}
}
1) flexbox 가장 바깥쪽 Container를 만들고 addSubview한다.
2) flexbox구조 정의(define)를 한다. define closure안에서 내가 만들 flexbox를 구조화 하면 된다.
예를들어 이런식이다.
import FlexLayout
self.rootFlexContainer.flex.define { (flex) in
flex.addItem(self.label)
flex.addItem(self.label2)
flex.addItem(self.label3)
}
2. Container를 Layout한다.
저러고 끝나는게 아니라, layoutSubviews()나 viewDidLayoutSubviews()에서
1) flexbox container를 Layout한다.
2) flex 메소드인 layout()을 사용하여 flexbox child를 layout한다.
코드로 보면
import PinLayout
import FlexLayout
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.rootFlexContainer.pin.all() // 1)
self.rootFlexContainer.flex.layout() // 2)
}
이런식이다. PinLayout의 pin을 이용해 container의 Layout을 먼저 잡아 준 뒤, child의 layout을 잡아준다.
FlexLayout을 사용한다면 거의 이런식으로 사용하게 될 것.
위 코드를 빌드하면
이런식으로 Layout이 잡히게 된다.
# Flexbox를 Define할 때..많이 쓰이는 것들?!
self.rootFlexContainer.flex.define { }
지금은 이런식으로 바로 define을 호출했지만, 여기서 이런저런 설정들을 할 수 있다.
[direction]
self.rootFlexContainer.flex.direction(.column).define { }
or
self.rootFlexContainer.flex.direction(.row).define { }
direction은 StackViews의 main axis를 결정하는 메소드라고 보면 된다.
기본적으로 direction이 column으로 설정되어있으므로, 만약 main axis가 column이라면
self.rootFlexContainer.flex.define { }
그냥 이렇게만 해도 되는 것이다.
[padding]
self.rootFlexContainer.flex.padding(12).define { }
이렇게 padding도 줄 수 있다.
viewDidLayoutSubviews에서 container를 layout할 때 줘도 되지만...이렇게 container 구조를 정의하는데서 주면 편리하다.
Padding을 넣게 되면
오른쪽 그림처럼 모든 방향에 Padding이 들어가게 된다.
[paddingTop, left, right, bottom]
padding()은 모든 방향이지만, 이렇게 방향을 지정해줄 수도 있다.
self.rootFlexContainer.flex.paddingTop(12).define { }
[paddingHorizontal, paddingHorizontal]
paddingHorizontal : left, right, start, end padding을 넣음
paddingVertical : top bottom padding을 넣음
ex.
self.rootFlexContainer.flex.paddingVertical(20).define { }
[backgroundColor]
self.rootFlexContainer.flex.backgroundColor(.gray)
backgroundColor도 flex에서 바로 지정이 가능하다.
[grow]
self.rootFlexContainer.flex.grow(1).define { }
flex item이 grow(성장)하는 기능을 정의한다.
item이 차지해야하는 flex container 내부의 사용가능한 공간을 나타낸다.
기본값은 0으로, view의 크기를 main-axis direction으로 유지한다.
ex. 모든 항목이 1로 설정되면 모든 child item이 container내부에서 동일한 크기로 설정된다.
child 중 한명에게 2의 값을 주면, 그 child는 다른 child보다 2배의 공간을 차지하게 된다.
말로 하면 잘 이해가 안갈 수 있는데, 코드로 예를 들어보자.
현재 코드는
self.rootFlexContainer.flex.define { (flex) in
flex.addItem(self.label)
flex.addItem(self.label2)
}
self.rootFlexContainer.pin.all()
self.rootFlexContainer.flex.layout()
이렇게 되어있다.
만약 grow를 flex item에 사용하게 되면,
self.rootFlexContainer.flex.define { (flex) in
flex.addItem(self.label).grow(1) ✅
flex.addItem(self.label2).grow(1) ✅
}
self.rootFlexContainer.pin.all()
self.rootFlexContainer.flex.layout()
이렇게 item이 grow(?..)되게 된다.
grow값을 다르게 줘보자.
self.rootFlexContainer.flex.define { (flex) in
flex.addItem(self.label).grow(1)
flex.addItem(self.label2).grow(2) ✅
}
self.rootFlexContainer.pin.all()
self.rootFlexContainer.flex.layout()
두번째 Label은 첫번째 Label보다 2배의 공간을 차지하게 된다.
[justifyContent]
flex container의 main-axis에 따라 정렬을 정의하는 프로퍼티이다.
기본값은 justifyContent(.start) 이다.
어떤식으로 동작하는지 보고싶으면 문서를 참고하면 된다.
문서에 나와있는 FlexLayout Introduction examples를 이해하기 위한 프로퍼티와 메소드는 다 봤다.
마지막으로 child layout을 결정하는 layout()메소드만 보면 될 것 같다.
# layout()
self.rootFlexContainer.flex.layout()
위에서도 말했지만, 이 layout은 flex container child를 layout하는 메소드이다.
위 코드에서는 단순히 layout()으로 되어있지만, 사실 위 코드는
self.rootFlexContainer.flex.layout(mode: .fitContainer)
mode가 fitContainer로 지정되어있는 것이다. (fitContainer가 기본값이라는 뜻)
mode는 총 3가지로
- fitContainer - 기본값. child는 container의 크기(width, height)내에 배치된다.
- adjustHeight - child는 container의 너비만 사용하여 layout된다. container의 높이는 flexbox의 child에 맞게 조정된다.
- adjustWidth - child는 container의 높이만 사용하여 layout된다. container의 너비는 flexbox의 child에 맞게 조정된다.
가 있다.
예를 들어보자. 현재 container가
이렇게 view를 꽉채우고 있는데,
self.rootFlexContainer.pin.all()
이 코드 때문에 당연하다.
여기서
self.rootFlexContainer.pin.all()
self.rootFlexContainer.flex.layout(mode: .adjustHeight)
이렇게 mode를 adjustHeight으로 바꿔주면,
adjustHeight - child는 container의 너비만 사용하여 layout된다. container의 높이는 flexbox의 child에 맞게 조정된다.
adjustHeight의 정의대로 container의 높이는 child에 맞게 조정된 것을 볼 수 있다.
대충 이정도면 FlexLayout을 사용하여 복잡한..StackView를 간단히 만들 수 있을 것 같다!!
참고
'공부' 카테고리의 다른 글
FlexLayout (2) (0) | 2021.05.05 |
---|---|
앱 종료하기 with animation (2) | 2021.05.04 |
extension Reactive (1) | 2021.04.28 |
PinLayout 사용해보기 (0) | 2021.04.21 |
Carthage 사용해보기 (0) | 2021.04.17 |
- iOS delegate
- WWDC
- Git
- swift delegate
- 피아노
- np-hard
- Xcode
- IOS
- Swift
- github
- np-complete
- WKWebView
- 회고
- swift 공부
- ios 13
- Accessibility
- FLUTTER
- 스위프트
- Combine
- 스위프트 문법
- actor
- fastlane
- swift array
- WidgetKit
- swift sort
- UIBezierPath
- SwiftUI
- 제이슨 파싱
- swift tutorial
- swift3
- Total
- Today
- Yesterday