SwiftUI frame 的參數三兩事(二)

之前寫過一篇 frame 的參數三兩事,但說明的有點細不太容易理解,最近對這幾個參數有另外一番認識,補充一篇。

修飾器 frame() 是用來調整元件大小,其參數除了 alignment 用來讓內容靠「上、下、左、右」等方向對齊外,其餘設定元件大小的參數總共有八個並分成四對,使用時要成對使用,如下:

  • 指定元件長寬大小:width / height
  • 長寬不能超過父元件範圍:maxWidth / maxHeight
  • 長寬不可小於子元件範圍:minWidth / minHeight
  • 長寬與子元件大小一樣:idealWidth / idealHeight

先撰寫下面程式碼。最外面的 VStack 當成父元件大小為(300, 300),最裡面的 Text 作為子元件大小為(100, 100),夾在中間的 HStack 就是待會用來測試 frame 的四組參數用的。

struct FrameTest: View {
    var body: some View {
        VStack {
            HStack {
                Text("Hello, World!")
                    .frame(width: 100, height: 100)
                    .border(.green)
            }
//            .frame(width: 350, height: 40)
//            .frame(minWidth: 350, minHeight: 40)
//            .frame(maxWidth: 350, maxHeight: 40)
//            .frame(idealWidth: 350, idealHeight: 400)
            .border(.blue)
        }
        .frame(width: 300, height: 300)
        .border(.black)
    }
}

width / height

不管父元件與子元件範圍,中間的 HStack 設定多大就多大,所以 HStack 的藍色邊界範圍為 (350, 40)。

VStack {
    HStack {
        Text("Hello, World!")
            .frame(minWidth: 100, minHeight: 100)
            .border(.green)
    }
    .frame(width: 350, height: 40)
//    .frame(minWidth: 350, minHeight: 40)
//    .frame(maxWidth: 350, maxHeight: 40)
//    .frame(idealWidth: 350, idealHeight: 40)
    .border(.blue)
}
.frame(width: 300, height: 300)
.border(.black)
Frame None
Screenshot

minWidth / minHeight

元件範圍不可比子元件小,因此雖然 HStack 設定成 (350, 40),但最後藍色邊界範圍為 (350, 100)。

VStack {
    HStack {
        Text("Hello, World!")
            .frame(minWidth: 100, minHeight: 100)
            .border(.green)
    }
//    .frame(width: 350, height: 40)
    .frame(minWidth: 350, minHeight: 40)
//    .frame(maxWidth: 350, maxHeight: 40)
//    .frame(idealWidth: 350, idealHeight: 40)
    .border(.blue)
}
.frame(width: 300, height: 300)
.border(.black)
Frame Min

maxWidth / maxHeight

元件範圍不可比父元件大,因此雖然 HStack 設定成 (350, 40),但最後藍色邊界範圍為 (300, 40)。

VStack {
    HStack {
        Text("Hello, World!")
            .frame(minWidth: 100, minHeight: 100)
            .border(.green)
    }
//    .frame(width: 350, height: 40)
//    .frame(minWidth: 350, minHeight: 40)
    .frame(maxWidth: 350, maxHeight: 40)
//    .frame(idealWidth: 350, idealHeight: 40)
    .border(.blue)
}
.frame(width: 300, height: 300)
.border(.black)
Frame Max

idealWidth / idealHeight

元件範圍跟子元件一樣,因此 HStack 的藍色邊界範圍為 (100, 100)。

VStack {
    HStack {
        Text("Hello, World!")
            .frame(minWidth: 100, minHeight: 100)
            .border(.green)
    }
//    .frame(width: 350, height: 40)
//    .frame(minWidth: 350, minHeight: 40)
//    .frame(maxWidth: 350, maxHeight: 40)
    .frame(idealWidth: 350, idealHeight: 40)
    .border(.blue)
}
.frame(width: 300, height: 300)
.border(.black)
Frame Ideal

補充 – fixedSize()

使用 idealWidth / idealHeight 參數時,可以配合 fixedSize() 將元件範圍固定在 idealWidth / idealHeight 的值,所以最後 HStack 的大小為 (350, 40)。

VStack {
    HStack {
        Text("Hello, World!")
            .frame(minWidth: 100, minHeight: 100)
            .border(.green)
    }
//    .frame(width: 350, height: 40)
//    .frame(minWidth: 350, minHeight: 40)
//    .frame(maxWidth: 350, maxHeight: 40)
    .frame(idealWidth: 350, idealHeight: 40)
    .fixedSize()
    .border(.blue)
}
.frame(width: 300, height: 300)
.border(.black)
Frame Ideal Fixed

發表迴響