그 동안 자격증 공부와 iOS 강의를 듣느라 블로그에 소홀했다.
거의 한달 반 만에 블로그에 기록을 남기는 것 같다.
개인적으로 Notion에 기록을 남기기도 하고 정신도 없고...
아무튼,, 오늘은 스토리보드나 SanpKit 이 아닌
FlexLayout과 PinLayout을 이용해서 뷰를 그리는 것에 대해서 적어보겠다..!
1. FlexLayout, PinLayout
FlexLayout 은 iOS 의 StackView를 좀 더 빠르고 간편하게 지정하기 위해서 사용하는 라이브러리이다.
PinLayout은 SanpKit과 같이 뷰의 위치를 잡아주는데 SnapKit은 Contstraints를 기준으로해서 offset과 inset을 사용해 뷰를 잡는 것과 다르게 PinLayout은 CSS 를 사용하던 사람들에게 조금더 익숙한 Padding과 Margin을 사용한다. 후에 SwiftUI 를 사용해도 이런식으로 뷰를 정의하기 때문에 공부해두면 좋을 것 같았다.
기본적인 사용방법은 공식문서와, 다른 블로그에 좋은 글들이 많아서 생략하고 내가 겪었던 이슈에 대해서 기록하려고 한다.
https://github.com/layoutBox/PinLayout
https://github.com/layoutBox/FlexLayout
사용방법
- ViewController 에서의 사용법이다.
- 뷰 컴포넌트 선언
private var contentView = UIView()
private var topGreetingLabel = UILabel()
private var logo = UIImageView()
private var bottomGreetingLabel = UILabel()
private var startButton = CSButton(.primary)
- attribute에서 속성을 지정해준다.
override func attribute() {
super.attribute()
topGreetingLabel.do {
$0.text = "날씨블리에 오신 걸\n환영해요!"
$0.numberOfLines = 0
$0.textAlignment = .center
$0.font = .boldSystemFont(ofSize: 25)
}
...
logo.do { ... }
bottomGreetingLabel.do { ... }
startButton.do { ... }
}
3. layout() 에서 layout을 잡아준다.
container.flex.alignItems(.center).define { flex in
flex.addItem(topGreetingLabel)
flex.addItem(logo).minHeight(201)
flex.addItem(bottomGreetingLabel)
flex.addItem(startButton).width(304).height(62)
}
4. flexLayout 을 이용해서 BaseViewController 에서 view에 addSubView 헀던 containe에 컴포넌트를 추가한다.
- pinLayout을 이용해서 뷰 사이의 거리를 정의한다.
올바른 코드
topGreetingLabel.pin.top(view.pin.safeArea.top + 93).left(30).right(30)
logo.pin.top(to: topGreetingLabel.edge.bottom).marginTop(58).left(126).right(126)
bottomGreetingLabel.pin.top(to: logo.edge.bottom).marginTop(100).left(95).right(95)
startButton.pin.top(to: bottomGreetingLabel.edge.bottom).marginTop(69).left(43).right(43)
- 문제상황
- 모든 컴포넌트들을 배치시킬 때 view 전체에 대해서 거리를 잡아줘야하나 했다 → 화면이 깨지고 실제로 모든 디바이스에서 제대로 작동할지 미지수 였다.
문제코드
topGreetingLabel.pin.top(view.pin.safeArea.top + 93).left(30).right(30)
logo.pin.top(contentView.pin.safeArea.top + 224).left(126).right(126)
bottomGreetingLabel.pin.top(view.pin.safeArea.top + 652).left(95).right(95)
startButton.pin.top(view.pin.safeArea.top + 652).left(43).right(43)
- 해결책
- pin.top( ) 메소드가 다른걸 볼 수 있는데, top( )의 파라미터는 CGFloat이다. 그래서 아무리 다른 뷰를 기준으로 거리를 잡고 싶어도 타입에러가 났다. 이상하게 flexView로 정의했던 뷰에는 먹었는데, 이건 아무래도 flexlayout의 기능같다.
- pin.top(to: ) 라는 메소드가 있는걸 발견했는데 이 메소드의 파라미터 타입은 ViewEdge다.
- 공식문서Edge링크
- edge를 사용하면 다른 뷰의 위치에 접근가능하다.
- 원하는 edge의 .margin 을 사용해서 거리를 정의한다.
PS.
그 외에도 뷰와 뷰 사이에 뷰를 끼워넣을때 betweenVercally 또는 betweenHorizontaly 나 after,before 를 사용해서 끼워넣기도 한다.
'iOS' 카테고리의 다른 글
[iOS][Swift][UIKit] UIPickerView의 그라데이션넣기(gradient). (0) | 2023.09.04 |
---|---|
[iOS][fastlane] 자동배포, testFilght 올리기 (0) | 2023.09.03 |
[iOS]UITextField, Delegate, 텍스트필드 구현, 글자수 제한하기 (0) | 2023.04.08 |
[iOS]This method should not be called on the main thread as it may lead to UI unresponsiveness. Thread 관련 문제? (2) | 2023.03.21 |
[iOS] Swift 의 lazy Variables의 특징과 사용시 고려사항 (0) | 2023.01.14 |