接續前篇,繼續畫 Mac mini M4 的底部。
官網上的圖片是這樣:

這一面最大的挑戰,是要怎麼畫出一整圈的散熱孔,以及塑膠殼與金屬機殼的同心圓角。如果你知道方法的話,其實很簡單。但我強烈建議你不要看答案,先自己想想看。
這是我的實作與 Preview 截圖:

MacminiM4BottomView 與 Preview
練習用的程式碼如下,完整版放在文章最後:
import SwiftUI
struct MacminiM4BottomView: View {
private let bodyWidth = 512.0
var body: some View {
chassis
.aspectRatio(1, contentMode: .fit)
.frame(width: bodyWidth)
.foregroundStyle(Color(white: 0.7))
.overlay {
plasticCover
}
.overlay {
vents
.frame(height: bodyWidth * 0.8)
}
.overlay {
macMiniLogo
}
.overlay(alignment: .topTrailing) {
powerButton
}
}
private var chassis: RoundedRectangle {
RoundedRectangle(cornerRadius: bodyWidth / 4)
}
@ViewBuilder
private var plasticCover: some View {
ContainerRelativeShape()
.aspectRatio(1, contentMode: .fit)
.foregroundStyle(Color(white: 0.2))
.padding(bodyWidth / 50)
.containerShape(chassis)
}
@ViewBuilder
private var vents: some View {
ZStack {
// 試著自行實作
}
}
@ViewBuilder
private var macMiniLogo: some View {
Text("Mac mini")
.font(.system(size: bodyWidth / 12))
.fontWeight(.medium)
.foregroundStyle(Color(white: 0.1))
}
@ViewBuilder
private var powerButton: some View {
Button(
action: {},
label: {
Circle()
.foregroundStyle(Color(white: 0.1))
.frame(width: bodyWidth / 12)
.overlay {
Image(systemName: "power")
.foregroundStyle(Color.white)
}
.padding(bodyWidth / 9)
}
)
}
}
#Preview {
MacminiM4BottomView()
}
macMiniLogo
與 powerButton
相對簡單,我就不做說明了。
塑膠殼與金屬機殼的同心圓角
金屬外殼 chassis
使用 RoundedRectangle
。而它裡面一圈的則是黑色的塑膠殼。這部分的小挑戰是,怎樣畫出同心(concentric)的圓角?
我們可以使用 ContainerRelativeShape
,並且用 .containerShape
指定它的 container 形狀就等於是 chassis
這個 RoundedRectangle
。這樣子我們就不用自行計算內圈的 cornerRadius 要減多少,直接達到同心的效果。