元件化
將畫面中不同的元件 (component) 寫成一個獨立的 View,讓程式碼可以更有組織,也可讓主程式更精簡。
Last updated
將畫面中不同的元件 (component) 寫成一個獨立的 View,讓程式碼可以更有組織,也可讓主程式更精簡。
Last updated
「縮放、平移、旋轉」 view:
.scaleEffect() .offset() .rotationEffect() .rotation3DEffect()
設定 view 的「渲染模式」:
.blendMode() (#todo:研究渲染模式如何使用?)
幫 view 設「陰影」: .shadow(radius:)
/*
Design+Code - SwiftUI for iOS 13
https://designcode.io/swiftui-layout-and-stacks
https://designcode.io/swiftui-components-and-visual-effects
*/
import SwiftUI
import PlaygroundSupport
struct ContentView: View {
var body: some View {
ZStack {
TitleView()
BackCard(.purple)
.scaleEffect(0.9) // 縮放
.offset(x: 0, y: -40) // 平移
.rotationEffect(.degrees(10)) // 旋轉
.rotation3DEffect(.degrees(10), axis: (x: 1, y: 0, z: 0)) // 3D 軸轉
.blendMode(.hardLight) // 渲染模式
BackCard(.pink)
.scaleEffect(0.95)
.offset(x: 0, y: -20)
.rotationEffect(.degrees(5))
.rotation3DEffect(.degrees(5), axis: (x: 1, y: 0, z: 0))
.blendMode(.hardLight)
Card()
.blendMode(.hardLight)
BottomCard()
} //
// 讓外框自動採用「最大的寬度與高度」(而不是採用最小的)
// ⚠️ 注意:
// 不要寫成 `frame(width: .infinity, height: .infinity)`
// 否則會當掉!
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.white)
}
}
PlaygroundPage.current.setLiveView(ContentView())
import SwiftUI
public struct Card: View {
// init
public init() {}
// view body
public var body: some View {
// 卡片最外框
VStack(spacing: 0) {
// 卡片標題區:UIDesign & Swift logo
HStack {
// 文字區塊
VStack(alignment: .leading) { // 讓所有文字「靠左對齊」
Text("UI Design")
.font(.title) // 字體加大
.fontWeight(.semibold) // 字體加粗
Text("Certificate")
.foregroundColor(.blue)
}
Spacer() // 將「文字區塊」與「Swift 商標」推向兩側
// Swift 商標圖
Image(uiImage: #imageLiteral(resourceName: "swift.png"))
.resizable() // 讓圖的大小「隨外框調整」(而不是用原尺寸)
.clipShape(Circle()) // 將圖修為「圓形」
.frame(width: 40, height: 40) // 限制尺寸為 40x40
} // 卡片標題區
.padding(.horizontal, 20) // 左右留白 20
.padding(.top, 20) // 上面留白 20
// 卡片設計圖
Image(uiImage: #imageLiteral(resourceName: "UNESCO.png"))
.resizable() // 讓圖的大小「隨外框調整」(而不是用原尺寸)
.aspectRatio(contentMode: .fill) // 讓圖片「保持原比例」⭐️
// ⭐️ 設定圖片大小,並讓圖片「靠上緣對齊」(而不是預設的「置中」)
.frame(width: 300, height: 140, alignment: .top)
} // 卡片最外框
// ⭐️ 讓卡片內容「靠上緣對齊」(而不是預設的「置中」)
.frame(width: 340, height: 220, alignment: .top)
.background(Color.black)
.cornerRadius(20) // 將卡片「裁成圓角」
.shadow(radius: 20) // 讓卡片有「陰影」
}
}
import SwiftUI
// 第一張卡片後面的卡片
public struct BackCard: View {
var color: Color
// init
public init(_ color:Color = .blue) {
self.color = color
}
// view body
public var body: some View {
VStack {
Spacer()
} //
.frame(width: 340, height: 220)
.background(color)
.cornerRadius(20)
.shadow(radius: 20)
}
}
import SwiftUI
// 畫面下方的「文字卡」
public struct BottomCard: View {
public init() {}
public var body: some View {
VStack(spacing: 20) {
// 文字卡的「小手把」
Capsule()
.fill(Color.black)
.frame(width: 40, height: 5)
.opacity(0.2)
// 文字
Text("This certificate is proof that Ben To has achieved the UI Design course with approval from a Design+Code instructor.")
.foregroundColor(Color.black)
// 將文字推倒最上方
Spacer()
}//
.padding(.top, 8)
.padding(.horizontal, 20)
.background(Color.white) // ⚠️ 注意:如果沒有設「背景色」,下面的「陰影」會沒有效果!
.cornerRadius(30)
.shadow(radius: 20)
.offset(y: 450) // 將文字卡往下方推
}
}
import SwiftUI
// 畫面的標題與主圖
public struct TitleView: View {
public init() {}
public var body: some View {
VStack{
// 標題
HStack{
Text("Certificates")
.foregroundColor(.black)
.font(.largeTitle)
.fontWeight(.bold)
Spacer() // 將文字向左推
}.padding()
// 主圖
Image(uiImage: #imageLiteral(resourceName: "UNESCO.png"))
.resizable() // 讓圖片「隨著環境的大小伸縮」
.aspectRatio(contentMode: .fit) // 讓圖片保持原比例
// 將文字與圖片往上推
Spacer()
}.padding()
}
}
Design+Code - SwiftUI for iOS 13
Apple doc