Notice
Recent Posts
Recent Comments
Link
관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - SwiftUI] ScrollView, VStack안에 Spacer 적용 방법 본문

iOS 응용 (SwiftUI)

[iOS - SwiftUI] ScrollView, VStack안에 Spacer 적용 방법

jake-kim 2025. 4. 2. 01:17

ScrollView안에 Spacer 적용하는 케이스

  • ScrollView안에 Spacer를 잘 활용해야하는 아래와같은 경우가 존재

ex) button은 항상 디바이스 하단에 떠 있고, 그 뒤에 스크롤되는 2개의 텍스트가 있는 경우 ("iOS앱 개발 알아가기", "jake") 

  • 상단의 Text가 짧을때는, "jake" Text는 하단 SafeArea로 부터 56만큼 간격 유지
  • 상단의 Text가 길어져서 스크롤이 많이 가능하게되면 "jake"는 스크롤 영역이므로 스크롤 밑쪽에 위치
상단이 짧은 텍스트 상단이 긴 텍스트
f
  • 구현방법은 상단 Text와 하단 Text 사이에 Spacer()를 넣고, 하단 패딩을 주는 방법이 있는데, ScrollView안에 Spacer()를 그대로 사용하면 동작하지 않음

ex) ScrollView안 VStack내부에 Spacer를 사용해도 UI를 보면 붙어있음

var body: some View {
    ZStack(alignment: .bottom) {
        contentView
        
        button
    }
}

var contentView: some View {
    ScrollView {
        HStack { // 스크롤을 디바이스 너비로 하기 위한 코드
            Spacer()
        }
        
        VStack {
            Text("iOS앱 개발 알아가기")
            Spacer()
            Text("jake")
            
            Spacer().frame(height: 56)
        }
    }
}

결과)

ScrollView안 VStack내부에 Spacer를 사용해도 UI를 보면 붙어있음

  • Spacer 적용이 안되는 이유는 아래에서 계속

ScrollView내부에 Spacer 사용하기

  • Spacer(minLength:)는 최대한 늘리고, 주어진 파라미터 minLength를 기준으로 최소크기만 맞추는 기능인데, ScrollView는 내부 콘텐츠 크기에 따라 무한히 확장될 수 있으므로 최대에 대한 기준이 없기 때문에 Spacer가 동작하지 않음
    • ScrollView내부에 Spacer를 사용하려면 ScrollView의 프레임 크기를 정해주면 됨
    • ScrollView 프레임 크기가 정해지면 Spacer는 최대로 얼만큼 늘릴지 알 수 있기 때문
  • scrollView의 크기를 정해주기 위해서, GeometryReader를 통해 내부 VStack에 minHeight를 지정해주면 해결
var contentView: some View {
    GeometryReader { proxy in
        ScrollView {
            HStack { // 스크롤을 디바이스 너비로 하기 위한 코드
                Spacer()
            }
            
            VStack {
                Text("iOS앱 개발 알아가기")
                Spacer()
                Text("jake")
                
                Spacer().frame(height: 56)
            }
            .frame(minHeight: proxy.size.height)
        }
        .frame(width: proxy.size.width)
    }
}

전체 코드) 

struct ContentView: View {
    @State var size = CGSize.zero
    
    var body: some View {
        ZStack(alignment: .bottom) {
            contentView
            
            button
        }
    }
    
    var contentView: some View {
        GeometryReader { proxy in
            ScrollView {
                HStack { // 스크롤을 디바이스 너비로 하기 위한 코드
                    Spacer()
                }
                
                VStack {
                    Text("iOS앱 개발 알아가기")
                    Spacer()
                    Text("jake")
                    
                    Spacer().frame(height: 56)
                }
                .frame(minHeight: proxy.size.height)
            }
            .frame(width: proxy.size.width)
        }
    }
    
    var button: some View {
        Button {
            print()
        } label: {
            Text("button")
        }
    }
}
Comments

jake-kim님의
글이 좋았다면 응원을 보내주세요!