[SwiftUI] 8. View Layout: view 사이의 간격 조정

Sean·2023년 5월 3일
0

SwiftUI_튜토리얼

목록 보기
8/11

참고 자료: SwiftUI 튜토리얼 공식문서

이제 막 SwiftUI를 배워보는 한 사람으로서, 코드 작성하고 내가 이해 한 대로 작성할것이다.

이 글의 내용은 위에 있는 참고자료의 공식문서를 번역하여 조금 더 내가 느끼기에 자연스럽게 만들어서 작성하는것이다.

누군가에게 알려주기보다 자신이 정리를 하면서 다시 문서를 보고 어버버거리지 않게 다시 참고하기 위함이기에 해당 문서를 읽는 사람은 swift에 대해서 어느 정도 안다는 가정하에 글을 작성할것이다

시작

Struct: Spacer

컨텐츠의 정렬 및 간격을 지정한다.
정보를 표시하는 view를 정의할 때 추가 공간이 어디에 있어야 하는지 선언해 레이아웃을 조정할 수 있다.
레이아웃을 적용하려는 방식에 따라 다른 도구를 선택할 수 있다.

Spacer 와 같이 view 에 인접한 공간에 영향을 주는 view 수정자도 존재 한다.
padding과 같이 view 옆에 영향을 미치는 도구이다.

경우에 따라 view나 수정자의 매개 변수로 기본값이 아닌 값을 제공해 레이아웃을 변경할 수 있다.

분석

1. 컨텐츠 정의

소스코드

TrainCar.swift

  import SwiftUI

enum TrainSymbol: String {
    case front = "train.side.front.car"
    case middle = "train.side.middle.car"
    case rear = "train.side.rear.car"
}

struct TrainCar: View {
    let position: TrainSymbol
    let showFrame: Bool
    
    init(_ position: TrainSymbol, showFrame: Bool = true) {
        self.position = position
        self.showFrame = showFrame
    }
    var body: some View {
        Image(systemName: position.rawValue)
            .background(Color("customPink"))
    }
}

struct TrainTrack: View {
    var body: some View {
        Divider()
            .frame(maxWidth: 200)
    }
}

struct TrainCar_Previews: PreviewProvider {
    static var previews: some View {
        TrainCar(.front)
    }
}

DefaultSpacing.swift

import SwiftUI

struct DefaultSpacing: View {
    var body: some View {
        Text("Default Spacing")
        HStack {
            TrainCar(.rear)
            TrainCar(.middle)
            TrainCar(.front)
        }
        TrainTrack()
    }
}

struct DefaultSpacing_Previews: PreviewProvider {
    static var previews: some View {
        VStack {
            DefaultSpacing()
        }
    }
}

view 사이의 간격 변경을 위한 몇가지 다른 방법을 보여주기 위해 열차를 사용한다.
앞, 중간, 뒷 부분의 3가지 view가 있다,
이러한 컨테이너 view에 기본적으로 일부 여백이 포함되어 있다.

이 커스텀 view 는 Image view의 범위를 표시하기 위해 분홍색 배경과 함께 기차의 SFSymbol를 표시하는 view를 정의한다.
각 위치에서 동일한 수정자와 매개변수를 지정하지 않고도 여러 위치에서 유사한 view를 가질 수 있도록 고유한 커스텀 view 를 정의할 수 있다.

두번째 샘플코드는 사용 중인 커스텀 view이다. 해당 view 선언은 그것이 나타내는 열차의 부분만 지정하고 해당 기호로 view를 정의하고 백그라운드를 추가한다.

이 코드는 전면, 중간, 후면의 HStack에 view 가 포함되어 기차를 형성한다. 이 코드는 view에 사용자 지정 공간이나 패딩을 추가하지 않지만 차량의 프레임 사이에는 약간의 공간이 존재 한다.
: HStack은 SwiftUI의 많은 내장 컬렉션 view와 마찬가지로 기본적으로 하위 view 사이에 약간 간격을 둔다.

2. 컨테이너 간격 맞춤 설정

소스코드

SpecificSpacing.swift

import SwiftUI

struct SpecificSpacing: View {
    var body: some View {
            Text("Specific Spacing")
            HStack(spacing: 20) {
                TrainCar(.rear)
                TrainCar(.middle)
                TrainCar(.front)
            }
            TrainTrack()
        }
}

struct SpecificSpacing_Previews: PreviewProvider {
    static var previews: some View {
        VStack {
            SpecificSpacing()
        }
    }
}

ScaledSpacing.swift

import SwiftUI

struct ScaledSpacing: View {
    @ScaledMetric var trainCarSpace = 5
    
    var body: some View {
        Text("Scaled Spacing")
        HStack(spacing:trainCarSpace) {
            TrainCar(.rear)
            TrainCar(.middle)
            TrainCar(.front)
        }
        TrainTrack()
    }
}

struct ScaledSpacing_Previews: PreviewProvider {
    static var previews: some View {
        VStack {
            ScaledSpacing()
        }
    }
}

HStack의 기본 간격은 모든 레이아웃에서 적합하지 않다.
스택의 하위 view 사이에 일정한 간격을 지정하거나 다이나믹 타입으로 크기가 조정되는 간격을 지정하거나 간격을 지정하지 않을 수 있다.

spacing매개변수는 view HStack 사이의 간격을 지정할 수 있다.

3. 하위 view에 패딩 추가

소스코드

DefaultPadding.swift

import SwiftUI

struct DefaultPadding: View {
    var body: some View {
        Text("Default Padding")
        HStack {
            TrainCar(.rear)
            TrainCar(.middle)
                .padding()
                .background(Color("customBlue"))
            TrainCar(.front)
        }
        TrainTrack()
    }
}

struct DefaultPadding_Previews: PreviewProvider {
    static var previews: some View {
        VStack {
            DefaultPadding()
        }
    }
}

PaddingSomeEdges.swift

import SwiftUI

struct PaddingSomeEdges: View {
    var body: some View {
        Text("Padding Some Edges")
        HStack {
            TrainCar(.rear)
            TrainCar(.middle)
                .padding([.leading])
                .background(Color("customBlue"))
            TrainCar(.front)
        }
        TrainTrack()
    }
}

struct PaddingSomeEdges_Previews: PreviewProvider {
    static var previews: some View {
        VStack {
            PaddingSomeEdges()
        }
    }
}

SpecificPadding.swift

import SwiftUI

struct SpecificPadding: View {
    var body: some View {
        Text("Specific Padding")
        HStack {
            TrainCar(.rear)
            TrainCar(.middle)
                .padding(5)
                .background(Color("customBlue"))
            TrainCar(.front)
        }
        TrainTrack()
    }
}

struct SpecificPadding_Previews: PreviewProvider {
    static var previews: some View {
        VStack {
            SpecificPadding()
        }
    }
}

view의 외부 가장자리에 패딩을 추가해 해당 view와 인접한 view사이 window의 가장자리 또는 scene에 약간의 공간을 둘 수 있다.

샘플코드 첫번째 에서 패딩에 매개변수가 없으면 네 가장자리 모두에 공간이 생긴다.
기본 패딩의 크기는 view의 속성과 view가 나타나는 환경에 따라 다르다.
패딩의 매개변수에 따라 view의 패딩이 변화 되는것을 보여주고 있다.

4. view를 추가하여 공간 만들기

소스코드

AddingSpacer.swift

import SwiftUI

struct AddingSpacer: View {
    var body: some View {
        Text("Spacer")
        HStack {
            TrainCar(.rear)
            Spacer()
            TrainCar(.middle)
            Spacer()
            TrainCar(.front)
        }
        TrainTrack()
    }
}

struct AddingSpacer_Previews: PreviewProvider {
    static var previews: some View {
        VStack {
            AddingSpacer()
        }
    }
}

AddingPlaceholder.swift

import SwiftUI

struct AddingPlaceholder: View {
    var body: some View {
        Text("Spacing with a Placeholder")
        HStack {
            TrainCar(.rear)
            TrainCar(.middle)
                .opacity(0)
                .background(Color("customBlue"))
            TrainCar(.front)
            
        }
        TrainTrack()
    }
}

struct AddingPlaceholder_Previews: PreviewProvider {
    static var previews: some View {
        VStack {
            AddingPlaceholder()
        }
    }
}

StackingPlaceholder.swift

import SwiftUI

struct StackingPlaceholder: View {
    var body: some View {
        Text("Stacking with a Placeholder")
        HStack {
            TrainCar(.rear)
            ZStack {
                TrainCar(.middle)
                    .font(.largeTitle)
                    .opacity(0)
                    .background(Color("customBlue"))
                TrainCar(.middle)
            }
            TrainCar(.front)            
        }
        TrainTrack()
    }
}

struct StackingPlaceholder_Previews: PreviewProvider {
    static var previews: some View {
        VStack {
            StackingPlaceholder()
        }
    }
}

컨텐츠 view를 수정하여 공간을 만드는 것 외에도 컨텐츠를 표시하지 않고 레이아웃을 수정하기 위해 보이지 않는 view를 추가하여 공간을 만들 수 있다.

각 Spacer에 대해 최소 너비를 지정할 수 도 있고, 인접한 내용이 모든 공간을 필요로 하는 경우에는 0으로 해줄 수 있다.

opacity()는 해당 view가 보이지 않더라도 공간을 차지하게 함으로서 view의 크기에 따라 달라지는 공간의 양을 지정한다.

ZStack은 가장 큰 view에 적응하므로 이 스택에서 보이지 않는 view는 중앙 열차 주변에 패딩과 같은 모양을 만든다.

참고자료

Struct: Spacer

기타

당연 틀린 부분 지적은 감사하나 비난은 정중하게 사양하겠다.

  • 음...레이아웃 관련된 부분은 그냥 대충 어떤걸 쓰는지만 알고 빠르게 코드 짜면서 실전에서 터득하는게 훨씬 빠를것 같다.
    그래서 글을 쓰고는 있지만 뭔가 그냥 형식적인 느낌(?)으로 쓰고 있다.
profile
"잘 할 수 있을까?"를 고민하기보단 재밌어 보이는건 일단 하고, 잘하기 위해 그냥 계속합니다.

0개의 댓글