SwiftUI로 구성하는도중 ZStack에 백그라운드 이미지를 깔고 컨텐츠를 중앙에 작성해야하는 UI가 있었다.
MainGradientZStack이란 코드를 작성하고, 그 content로 UI를 받을수 있게 작성하였다
import SwiftUI
struct MainGradientZStack<Content>: View where Content: View {
let content: () -> Content
init(@ViewBuilder content: @escaping () -> Content) {
self.content = content
}
var body: some View {
ZStack {
Image("bgGradient")
.resizable()
.aspectRatio(contentMode: .fill)
.edgesIgnoringSafeArea(.all)
content()
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
이해한 ZStack은 겹겹히 쌓아올릴수 있는 UI로 이해하고 있었다.
그러니 Image는 하단에 있고, content는 상단레이어에 그려질것을 기대했고 실제로 그려졌다
여기까진 괜찮다.
요소중 maxWidth가 .infinity를 쓰기 전까지 말이다.
커스터마이징 다이얼로그를 하나 그린다고 생각하자
overlay가 .infinity로 풀사이즈이고 안에 버튼또한 .infinity로 1:1 비율로 버튼이 배치되어있다
cornerRadius까지 적용하여 둥근모서리를 만들었으나 아래와같이 보여졌다.
핸드폰 프레임에 덮어씌워진 모습이다.
왜 이런 현상이 일어났을까?
기본적으로 Stack들은 자식의 사이즈를 따라간다.
백그라운드 이미지가 부모를 벗어날경우 생긴 이슈인데 이미지 가로길이가 벗어났고, safeArea가 있는 디바이스에서만 발생하였다.
이를 해결하는 방법은 두가지가있다.
struct MainGradientZStack<Content>: View where Content: View {
let content: () -> Content
init(@ViewBuilder content: @escaping () -> Content) {
self.content = content
}
var body: some View {
GeometryReader { geometry in
ZStack {
Image("bgGradient")
.resizable()
.aspectRatio(geometry.size, contentMode: .fill)
.edgesIgnoringSafeArea(.all)
.frame(maxWidth: .infinity, maxHeight: .infinity)
content()
}.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
}
struct MainGradientZStack<Content>: View where Content: View {
let content: () -> Content
init(@ViewBuilder content: @escaping () -> Content) {
self.content = content
}
var body: some View {
ZStack {
content()
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(
Image("bgGradient")
.resizable()
.aspectRatio(contentMode: .fill)
.edgesIgnoringSafeArea(.all)
.frame(maxWidth: .infinity, maxHeight: .infinity)
)
}
}
의미상 background가 맞는겉같아 2번의 방법으로 해결하였다.