티스토리 뷰

반응형

FlowLayout

 

 

import SwiftUI

/// 컨텐츠 크기 만큼 아래로 배치 되는 레이아웃 iOS 16+
struct FlowLayout: Layout {
    var spacing: CGFloat? = nil
    
    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
                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
                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) {
                ForEach(array.indices, id: \.self) {
                    Text(array[$0])
                        .font($0.isMultiple(of: 2) ? .title : .title2)
                        .border(Color.red)
                        .padding(.bottom, 10) // FlowLayout 에서 줄 간격 설정 방법을 못 찾아서 이렇게 추가
                }
            }
        }
    }
}



 

출처

https://swiftwithmajid.com/2022/11/16/building-custom-layout-in-swiftui-basics

 

Building custom layout in SwiftUI. Basics.

Nowadays, SwiftUI provides the Layout protocol allowing us to build super-custom layouts by digging into the layout system without using GeometryReader. Layout protocol brings us the incredible power of building and reusing any layout you can imagine. This

swiftwithmajid.com

https://swiftwithmajid.com/2022/12/06/building-custom-layout-in-swiftui-spacing

 

Building custom layout in SwiftUI. Spacing.

Multiple layouts allow us to compose views in different ways. One crucial thing is the spacing between children of the concrete layout. This week we will learn how to build a custom layout allowing us to specify a particular spacing between views and how t

swiftwithmajid.com

iOS

Swift

Xcode

반응형
댓글
300x250
반응형
최근에 올라온 글
최근에 달린 댓글
«   2024/04   »
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
Total
Today
Yesterday