簡介
最近在學習 SwiftUI ,我一般都是先去學習界面布局,所以就想著仿寫一下經常使用的軟體的界面,所以先拿微信開刀,因為不想一次性發太多的內容,所以只好將主題分解,一部分一部分地去講,接下來我們一起來學習吧,
如果你嘗試過使用 SwiftUI 撰寫界面,你會發現是如此地舒心,我已深深地愛上了它,當然它的坑并不少,畢竟才剛出來,最低支持系統是 iOS13,估計還得等個幾年才會慢慢在公司里使用上吧,但是這并不妨礙我們的學習,
在這篇文章里,我會一步一步撰寫微信的首頁串列視圖,一步一步將代碼呈現上來,并仔細地講解,我相信你們都可以看懂的,先來看看效果圖,
很簡單吧?是很簡單,但是在撰寫的時候還是有些技巧在里面,畢竟,簡單才不容易勸退嘛,在開始前先講一下這篇文章將會用到的一些布局與組件,先給大家一個印象,方便后面的閱讀理解,
HStack - 水平布局
VStack - 垂直布局
Text - 文本控制元件
Spacer - 擴展空間,使容器填滿布局空間
Image - 影像控制元件
List - 串列控制元件
Divider - 分隔線控制元件
作業環境
Xcode - Version 11.3.1 (11C504)
Swift - version 5.1.3 (swiftlang-1100.0.282.1 clang-1100.0.33.15)
開始撰寫代碼
撰寫串列行
我們來先把頭像添加進來,
Image("1")
.resizable() // 1
.frame(width: 46, height: 46) // 2
.cornerRadius(6)// 3
1 - 在 SwiftUI 中,如果需要控制影像的大小,則必須先呼叫resizable修飾
2- 設定影像大小
3 - 設定圓角大小,四個角的大小都相同
因為布局是橫向的,所以我們在外層使用HStack包裹起來,然后添加聯系人名字和最后發訊息時間,
HStack {
// 頭像
HStack {
Text("女神")
.font(.body) // 1
Spacer()
Text("下午 2:55")
.font(.caption)
.foregroundColor(Color.gray.opacity(0.5)) // 2
}
}
1 - 使用 font 修飾字體,這里使用了蘋果提供的標準字體,蘋果還提供了 largeTitle, title, headline, subheadline, body, callout, footnote, caption,
2 - 使用 foregroundColor 修飾字體顏色,因為 gray 的灰色還是太黑了,所以這里又使用了 opacity 去修飾透明度為50%,使它顯得更淡一點,
名字下方顯示的是是最后發送或接收的訊息內容,因此我們在外層使用 VStack 包裹起來,
VStack(alignment: .leading, spacing: 6) { // 1
// 名稱和時間
Text("對不起,你是個好人")
.font(.callout)
.foregroundColor(Color.gray)
}
// 1 - 設定
VStack里子控制元件居左對齊,默認是居中對齊,再設定子控制元件的間隙為 6 個像素,這樣比較符合微信上面的設計,
現在樣子已經出來了,我們先預覽下效果,
我們給最外層的HStack增加padding,使它更美觀一些,引數填寫.all代表四周都需要邊框,經過我的眼力觀察,它的默認是 16px 的樣子,
HStack {
// 頭像、名稱、時間、訊息內容
}
.padding(.all)
有了間距,好看多了,
接下來創建一個視圖,它負責裝載行視圖,起名為GCMainRow,
struct GCMainRow: View {
var body: some View {
HStack {
Image("1")
.resizable()
.frame(width: 46, height: 46)
.cornerRadius(6)
VStack(alignment: .leading, spacing: 6) {
HStack {
Text("女神")
.font(.body)
Spacer()
Text("下午 2:55")
.font(.caption)
.foregroundColor(Color.gray.opacity(0.5))
}
Text("對不起,你是個好人")
.font(.callout)
.foregroundColor(Color.gray)
}
}
.padding(.all)
}
}
然后在ContentView改為呼叫GCMainRow(),這樣代碼就好看很多了,
struct ContentView: View {
var body: some View {
GCMainRow()
}
}
撰寫串列 List
好了,現在讓我們來撰寫串列視圖吧,我們在最外層使用List包裹GCMainRow,回圈 20 個視圖,資料多點才可以讓我們滾動,
List(0 ..< 20) { _ in // 1
GCMainRow()
}
1 - 因為我們不需要用到回圈的一些資料,所以我們使用 _ 去忽略它,
List控制元件默認的都會有邊距,下圖黃色是GCMainRow的大小,可以看得出來旁邊有空白的填充,這對我們當前的設計來說不太友好,因此我們需要想辦法去掉這些邊距填充,
List提供了listRowInsets來控制行的邊距(上下左右),我們來試著使用一下,
List(0 ..< 20) { item in
GCMainRow()
.listRowInsets(EdgeInsets())
}
我們發現,這樣寫是沒有作用的,listRowInsets的生效條件是“不能直接在List中使用,需要配合For Each陳述句才能生效”,我們再修改一下代碼,
List {
ForEach(0 ..< 20) { item in
GCMainRow()
.listRowInsets(EdgeInsets())
}
}
好了,這次生效了,這就是我們要的結果,
自定義分隔線
我們仔細觀察一下分隔線,在微信里分隔線是左對齊在名稱和訊息內容的,所以我們需要把現有的分隔線隱藏掉,然后再實作它,
在這里講解一下,List是基于UITableView去實作的,這意味著我們可以通過appearance全域修改它的所有屬性,正如我們現在需要取消它默認的分隔線,將separatorStyle設定為.none即可,
init() {
UITableView.appearance().separatorStyle = .none
}
因為分隔線是貼著右邊緣的,所以我們需要在包裹著名稱、時間、訊息內容的VStack外層再包裹一層VStack,在其中再添加分隔線Divider,并將里層的VStack設定右邊距,最后將最外層的HStack的padding改為上和左邊距,是不是聽得有點懵?沒關系,看看代碼就很容易理解了,
HStack(alignment: .top) { // edit
// 頭像
VStack { // new
VStack(alignment: .leading, spacing: 6) {
// 名稱、時間、訊息內容
}
.padding(.trailing) // new
Divider() // new
}
}
.padding(.top) // edit
.padding(.leading) // edit
我們現在來看一下效果,
未讀訊息小紅點
未讀訊息在頭像的右上方,小紅點的中心點是位于頭像的右上頂端,我們可以使用overlay疊加一個視圖,來制作小紅點吧,
Image("1")
// ...
.overlay(
Color.red // 1
.frame(width: 16, height: 16)
.cornerRadius(8)
.offset(x: 23, y: -23) // 2
)
// 1 - Color 本身也是一個視圖組件,這是官方的定義 @available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *) extension Color : View { }
// 2 - 設定視圖的偏移量,那么23是怎樣得出來的呢?很簡單,因為默認的
overlay視圖是位于父視圖的中心,那么我們要將它放置在右上角,那么只需要寬高都除以2就可以了,那么這里的結果就是,x軸增加23px,y軸減少23px
接下來是未讀數量,和上面的相似,在Color視圖上利用overlay疊加Text視圖就可以了,
Color.red
.overlay( // 1
Text("1")
.font(.caption)
.foregroundColor(.white)
)
.frame(width: 16, height: 16)
.cornerRadius(8)
.offset(x: 23, y: -23)
// 1- 值得注意的是,因為文本也是需要偏移到右上角的,所以必須放在前面,不然它默認就是居中的
至此,代碼演示結束,預覽一下靜態圖,文章開頭有 gif 動態圖效果,
總結
好了,這篇文章就到這里,篇幅有點長了,不過沒關系,我們來總結一下關鍵點:
List默認是有行邊距的,要取消或修改它的行邊距,我們必須通過For Each再配合上listRowInsets才能實作,List是基于UITableView去實作的,這意味著我們可以通過appearance全域修改它的所有屬性,- 使用
overlay可以給視圖疊加一個視圖,
Demo 原始碼下載
我已經把 Demo 上傳至 GitHub 上面,專案名字是 SwiftUI-Tutorials,目錄名為GCWechatList,有需要的朋友可以去下載運行一下,當然你也可以跟著文章去做一遍,這樣更有利于你掌握此方面的知識,
文章篇幅有點長,雖然教的東西也挺簡單,但概述得比較詳細,任何東西都是先從簡單入手的,才不會造成勸退不是嗎?哈哈,此文章針對于新手而言還是很友好的,對于已經會的人來講就可能廢話有點多了,如果必須要噴,請輕噴,我比較玻璃心,
如果本文章對你有幫助,請關注我,你的關注就是我后續寫文章的動力,下期會更精彩噢!
關于作者
博文作者:GarveyCalvin
微博:https://weibo.com/feiyueharia
博客園:https://www.cnblogs.com/GarveyCalvin
本文著作權歸作者,歡迎轉載,但必須保留此段宣告,并給出原文鏈接,謝謝合作!
公眾號
作者第一次運營公眾號,請你們一定要關注我的公眾號,給我點動力,后期主要運營公眾號為主,這是第二篇發布的文章,需要你們的支持,謝謝你們!
QQ群
一起討論 SwiftUI,群主喜歡看熱鬧,當吃瓜人員,進來時填寫你在哪里看到此文章的,并介紹下自己,一句話就行,

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/2557.html
標籤:iOS
上一篇:iOS面試題---Objective_C語言特性:分類、擴展、代理、通知、KVO、KVC、屬性
下一篇:IOS App打包發布完整流程
