# 6作業: 從程式製作出美國國旗

用 Swift 語言建立美國國旗的畫面,其中包含紅色和白色條紋的背景,以及藍色背景上的星星。

程式碼中使用了 UIView、UIBezierPath 和 CAShapeLayer 等功能來創建和呈現這些元素,以及在 ViewController 內使用 #Preview 功能預覽視圖

首先,當然是先放上辛苦畫完的美國國旗的成果圖!

維基百科有尺寸可以參考,可依其提供的尺寸繪製

  1. 開新專案後,進入 ViewController ,在最下面加入 #Preview,右邊就會蹦出預覽視窗,可以在建構圖案的過程實時看見自己繪製的影像。
#Preview {
UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController()!
}

2. 接著先加入旗幟的紅色底圖

let redArea = UIView(frame: CGRect(x: 25, y: 100, width: 342, height: 180))
//建立名為 redArea 的 UIView 視圖,X與Y起始點位置,寬與高尺寸
redArea.backgroundColor = UIColor(red: 0.698, green: 0.132, blue: 0.203, alpha: 1)
//設定 redArea 的背景顏色為近紅色
redArea.layer.borderWidth = 1
//設定 redArea 的邊框寬度為 1
redArea.layer.borderColor = CGColor(red: 0, green: 0, blue: 0, alpha: 1)
//設定 redArea 的邊框顏色為黑色
view.addSubview(redArea)
//將 redArea 建立為 view 的 SubView 視圖呈現在畫面上

3. 使用 for loop 加入6根白長條

for i in 0 ... 5 {
//i 從 0 到 5 共循環 6 次
let whiteLine = UIView(frame: CGRect(x: 0, y: 13.842 + (13.842 * Double(i*2)), width: 342, height: 13.842))
//建立名為 whiteLine 的 UIView 視圖,並設定X與Y起始點+(增量尺寸),寬與高尺寸
whiteLine.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1)
//設定 whiteLine 的背景顏色為白色
whiteLine.layer.borderWidth = 1
//設定 whiteLine 的邊框寬度為 1
redArea.addSubview(whiteLine)
//將 whiteLine 建立為 redArea 的 SubView 視圖呈現在畫面上
}

4. 加入星星的藍色底圖

let blueArea = UIView(frame: CGRect(x: 0, y: 0, width: 136.8, height: 96.93))
//建立名為 blueArea 的 UIView 視圖,X與Y起始點在0的位置,並設定寬與高尺寸
blueArea.backgroundColor = UIColor(red: 0.234, green: 0.233, blue: 0.43, alpha: 1)
//設定 blueArea 的背景顏色為近紅色
blueArea.layer.borderWidth = 1
//設定 blueArea 的邊框寬度為 1
redArea.addSubview(blueArea)
//將 blueArea 建立為 redArea 的 SubView 視圖呈現在畫面上

5. 建立星星 function,方便直接製作每一顆星星,這顆星星的形狀是使用 UIBezierPath 繪製。

func starView(_ xPosition:Double,_ yPsition:Double) -> UIView{
//建立名為 starView 的 function,並可傳入每顆星星的X與Y座標後回傳一個星星的View
let path = UIBezierPath()
//將 UIBezierPath 生成為 path
//以 .move 為起始點,使用 .addLine 連接每個座標畫出線段,結束時使用 .close() 封閉圖形
path.move(to: CGPoint(x: 5.54, y: 0))
path.addLine(to: CGPoint(x: 6.79, y: 3.83))
path.addLine(to: CGPoint(x: 10.82, y: 3.83))
path.addLine(to: CGPoint(x: 7.56, y: 6.20))
path.addLine(to: CGPoint(x: 8.80, y: 10.03))
path.addLine(to: CGPoint(x: 5.54, y: 7.66))
path.addLine(to: CGPoint(x: 2.29, y: 10.03))
path.addLine(to: CGPoint(x: 3.53, y: 6.20))
path.addLine(to: CGPoint(x: 0.27, y: 3.83))
path.addLine(to: CGPoint(x: 4.30, y: 3.83))
path.close()
let starView = UIView(frame: CGRect(x: xPosition, y: yPsition, width: 30.8, height: 30.8))
//建立星星的視圖框架,X與Y為每顆星星的位置傳入值,寬與高為30.8
let starLayer = CAShapeLayer()
//建立名為 starLayer 的 CAShapeLayer 物件
starLayer.path = path.cgPath
//將所繪製的星星形狀 path.cgPath 賦值給 starLayer.path 顯示星星圖形
starLayer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
//定義星星內部的顏色為白色
starView.layer.addSublayer(starLayer)
//將星星(starView.layer)加到starView
return starView
//將星星的結果視圖回傳
}

6. 建立星星的迴圈,因為星星太多顆了,間距又是固定的,因此這邊使用 for 與 while 迴圈來佈置每顆星星的視圖,這邊迴圈修改了多次,把重複的步驟一一的簡化🤣。

for v in 1 ... 9 {
//總共有九排星星
var starAmount = 6
//第一排6顆星星
var starXStart = 5.854
//第一排的X起始位置
if v % 2 == 0 {starAmount = 5; starXStart = 17.248 }
//若為偶數排,則改變為五顆星星與X的起始位置,否則不修改
while starAmount > 0 {
redArea.addSubview(starView(starXStart + (11.394 * Double((starAmount-1)*2)), -4.144 + (9.684 * Double(v))))
starAmount -= 1
}
//當星星數量未被扣至0繼續往橫軸方向貼入星星 starView
}
疊圖順序

GitHub連結

參考資料

--

--