简体   繁体   中英

SwiftUI: Frame modifier in ZStack affecting other views

struct CircleTestView: View {
    let diameter: CGFloat = 433

    var body: some View {
        ZStack {
            Color(.yellow)
                .ignoresSafeArea()
        
            VStack {
                Circle()
                    .fill(Color(.green))
                    .frame(width: diameter, height: diameter)
                    .padding(.top, -(diameter / 2))
                Spacer()
            }
        
            VStack {
                Spacer()
                Button {} label: {
                    Color(.red)
                        .frame(height: 55)
                        .padding([.leading, .trailing], 16)
                }
            }
        }
    }
}

The code above creates the first image, yet for some reason if I remove the line the sets the frame for the Circle (ie. .frame(width: diameter, height: diameter) ) I get the second image.

  1. 在此处输入图像描述 2. 在此处输入图像描述

I want the circle how it is in the first screen, and the button how it is in the second screen, but can't seem to achieve this. Somehow setting the frame of the Circle is affecting the other views, even though they're in a ZStack . Is this a bug with ZStacks , or am I misunderstanding how they work?

Lets call this one approach a:

struct CircleTestView: View {
let diameter: CGFloat = 433

var body: some View {
    ZStack {
        Color(.yellow)
            .ignoresSafeArea()
    
        VStack {
            Circle()
                .fill(Color(.green))
                .frame(width: diameter, height: diameter)
                .padding(.top, -(diameter / 2))
            Spacer()
        }
    
        VStack {
            Spacer()
            Button {} label: {
                Color(.red)
                    .frame(height: 55)
            }
        }
        .padding(.horizontal, 16)
        }
    }
}

Lets call this one approach b:

struct CircleTestView: View {
let diameter: CGFloat = 433

var body: some View {
    ZStack {
        Color(.yellow)
            .ignoresSafeArea()
    
        VStack {
            Circle()
                .fill(Color(.green))
                .offset(x: 0, y: -(diameter / 1.00))
            // increment/decrement the offset by .01 example:
            // .offset(x: 0, y: -(diameter / 1.06))
            Spacer()
        }
    
        VStack {
            Spacer()
            Button {} label: {
                Color(.red)
                    .frame(height: 55)
                    .padding([.leading, .trailing], 16)
            }
         }
      }
   }
}

A combination of the two approaches would land you at approach c. Do any of these achieve what you are looking for?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM