티스토리 뷰
반응형
import SwiftUI
/// 컨텐츠 크기 만큼 아래로 배치 되는 레이아웃 iOS 16+
struct FlowLayout: Layout {
var spacing: CGFloat? = nil
var lineSpacing: CGFloat = 10.0 // 기본 줄 간격을 설정
struct Cache {
var sizes: [CGSize] = []
var spacing: [CGFloat] = []
}
func makeCache(subviews: Subviews) -> Cache {
let sizes = subviews.map { $0.sizeThatFits(.unspecified) }
let spacing: [CGFloat] = subviews.indices.map { index in
guard index != subviews.count - 1 else {
return 0
}
return subviews[index].spacing.distance(
to: subviews[index+1].spacing,
along: .horizontal
)
}
return Cache(sizes: sizes, spacing: spacing)
}
func sizeThatFits(
proposal: ProposedViewSize,
subviews: Subviews,
cache: inout Cache
) -> CGSize {
var totalHeight = 0.0
var totalWidth = 0.0
var lineWidth = 0.0
var lineHeight = 0.0
for index in subviews.indices {
if lineWidth + cache.sizes[index].width > proposal.width ?? 0 {
totalHeight += lineHeight + lineSpacing // 줄 간격 추가
lineWidth = cache.sizes[index].width
lineHeight = cache.sizes[index].height
} else {
lineWidth += cache.sizes[index].width + (spacing ?? cache.spacing[index])
lineHeight = max(lineHeight, cache.sizes[index].height)
}
totalWidth = max(totalWidth, lineWidth)
}
totalHeight += lineHeight
return .init(width: totalWidth, height: totalHeight)
}
func placeSubviews(
in bounds: CGRect,
proposal: ProposedViewSize,
subviews: Subviews,
cache: inout Cache
) {
var lineX = bounds.minX
var lineY = bounds.minY
var lineHeight: CGFloat = 0
for index in subviews.indices {
if lineX + cache.sizes[index].width > (proposal.width ?? 0) {
lineY += lineHeight + lineSpacing // 줄 간격 추가
lineHeight = 0
lineX = bounds.minX
}
let position = CGPoint(
x: lineX + cache.sizes[index].width / 2,
y: lineY + cache.sizes[index].height / 2
)
lineHeight = max(lineHeight, cache.sizes[index].height)
lineX += cache.sizes[index].width + (spacing ?? cache.spacing[index])
subviews[index].place(
at: position,
anchor: .center,
proposal: ProposedViewSize(cache.sizes[index])
)
}
}
}
struct ContentView: View {
let array = "다중 레이아웃을 사용하면 다양한 방식으로 뷰를 구성할 수 있습니다. 한 가지 중요한 것은 콘크리트 레이아웃의 하위 항목 사이의 간격입니다. 이번 주에 우리는 뷰 사이의 특정 간격을 지정할 수 있는 사용자 정의 레이아웃을 구축하는 방법과 SwiftUI에서 플랫폼 중심의 사전 정의된 간격 규칙을 준수하는 방법을 배울 것입니다.".split(separator: " ")
var body: some View {
VStack {
FlowLayout(spacing: 10, lineSpacing: 10) {
ForEach(array.indices, id: \.self) {
Text(array[$0])
.font($0.isMultiple(of: 2) ? .title : .title2)
.border(Color.red)
}
}
}
}
}
출처
https://swiftwithmajid.com/2022/11/16/building-custom-layout-in-swiftui-basics
https://swiftwithmajid.com/2022/12/06/building-custom-layout-in-swiftui-spacing
iOS
Swift
Xcode
반응형
'iOS SwiftUI' 카테고리의 다른 글
iOS SwiftUI Custom Slider 커스텀 슬라이더 (제어센터 UI) (0) | 2024.08.01 |
---|---|
[TIL] iOS SwiftUI 글자수, 단어수, 줄수 세기 + 복사, 공유, 툴바, 키보드 닫기 등 (0) | 2024.07.01 |
iOS SwiftUI 드래그 앤 드롭 Drag And Drop (DND) (0) | 2024.04.01 |
iOS SwiftUI PageControl 페이지 컨트롤 (0) | 2024.03.01 |
iOS SwiftUI TabView 의 tabItem 누를 때 탭 전환 대신, 네비게이션 이동 (0) | 2024.01.01 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- ios
- 심사
- SWIFT
- Xcode
- 로컬라이징
- SKProductsRequestDelegate
- 프로그레스
- Localizations
- 아이오에스
- TabBar
- 테이블뷰
- localizing
- 리젝
- SKPayment
- presentationcompactadaptation
- swiftUI
- indicator
- Localized
- 다국어
- 인디케이터
- TabView
- 스위프트
- Language
- Authorization
- 엑스코드
- AppStore
- permission
- SKPaymentTransactionObserver
- Reject
- custom segment
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
글 보관함