*SwiftUI is a modern way to declare user interfaces for any Apple platform. Create beautiful, dynamic apps faster than ever before.git
一種牛逼的更加快速,更加漂亮的用戶界面的方法編程
Landmarks
,一個能夠發現、分享你喜歡地點的App
)示例,來引導你們進行SwiftUI
開發。咱們將使用SwiftUI
框架來構建Landmark
詳情界面。Landmarks
利用stacks
將圖片和文本組合起來來進行視圖佈局。你須要引用MapKit
框架頭文件來建立一個地圖視圖。 你能夠經過Xcode
新的實時反饋功能,來優化你的視圖佈局 。SwiftUI
的新Xcode
項目。瀏覽畫布、預覽和SwiftUI
模板代碼。要在
Xcode
中預覽畫布上的視圖並與之交互,請確保您的Mac運行的是macOS 10.15 beta版
。swift
macOS 10.15 beta版下載地址 Xcode 11下載地址bash
點擊以後你就會感受發現了新東西咯:app
默認狀況下,SwiftUI視圖文件聲明兩個結構。框架
如今咱們來玩玩預覽:編輯器
若是畫布沒有展現出來,能夠經過 Editor > Editor and Canvas 顯示出來。ide
把Hello World更改成Hello SwiftUI! 當你修改文案後,SwiftUI會自動更新視圖。 工具
你有兩種方式來自定義TextView
。佈局
view
代碼inspector
檢查器來幫助你進行代碼編寫。當你構建Landmarks
的時候,你能夠運用任何一個編輯器來進行編碼工做:直接修改源代碼、經過畫布、經過inspector view
檢查器。代碼並不會關心你用什麼工具,它始終可以保持最新狀態
preview
畫布上,按住Command鍵+點按Text文本框
,這時候inspector
就會被喚起。 inspector
彈出框所展現的屬性也會由於不一樣的UI控件而有所不一樣。經過inspector檢查器
修改Text文本框的屬性。
.color(.green)
把文本修改爲綠色。SwiftUI視圖
,你能夠調用modifiers
方法。Modifiers
能夠修改視圖的屬性,而且modifier
返回一個新的視圖,因此一般會將多個modifiers
像鏈同樣垂直堆疊在一塊兒。( 鏈式編程)。import SwiftUI
struct ContentView: View {
var body: some View {
Text("Turtle Rock")
.font(.title)
.color(.green)
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
複製代碼
你編寫的代碼確定和view是一一對應的。當你經過inspector
修改了view
屬性以後,Xcode
會自動更新你的代碼。
這時候,打開inspector
,而後把文本Color屬性
修改成Inherited。
注意一點的就是,Xcode
會根據inspector
修改自動更新你的代碼。
咱們建立了一個文本框用來顯示landmark
的詳情信息,而且把這個文本控件放到頭部。 當咱們建立SwiftUI
視圖控件的時候,咱們會把控件的內容、佈局還有一些行爲放在body
屬性中;然而body
屬性只返回了一個view
。你能夠利用stacks
嵌入多個view
,它能夠垂直嵌入、水平嵌入等。 在這裏,咱們將使用垂直stack
來顯示park詳情信息
。
Command+
點按text初始化方法區域。選擇Embed in VStack
。
text view
到stack
中。Library面板
。拖拽一個text view
到 「Turtle Rock」後面 。修改text view
文案爲Joshua Tree National Park
。
設置text view
的字體。
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Text("Turtle Rock")
.font(.title)
Text("Joshua Tree National Park")
.font(.subheadline)
}
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
複製代碼
修改VStack
對齊方式。
import SwiftUI
struct ContentView: View {
var body: some View {
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
Text("Joshua Tree National Park")
.font(.subheadline)
}
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
複製代碼
若是不設置對齊方式,VStack
默認是內容垂直居中。
在面板中,Command+
點按 Joshua Tree National Park
喚起inspector
,選擇Embed in HStack
。
在location
後面添加一個新的文本框,修改文本框文案並設置字體
import SwiftUI
struct ContentView: View {
var body: some View {
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
HStack {
Text("Joshua Tree National Park")
.font(.subheadline)
Text("California")
.font(.subheadline)
}
}
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
複製代碼
Space
來適應寬度。Space
把父視圖在水平或者垂直方向上所有充滿。import SwiftUI
struct ContentView: View {
var body: some View {
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
HStack {
Text("Joshua Tree National Park")
.font(.subheadline)
Spacer()
Text("California")
.font(.subheadline)
}
}
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
複製代碼
最後,利用padding()
來設置邊距。
import SwiftUI
struct ContentView: View {
var body: some View {
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
HStack {
Text("Joshua Tree National Park")
.font(.subheadline)
Spacer()
Text("California")
.font(.subheadline)
}
}
.padding()
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
複製代碼
咱們已經把park名稱和位置的視圖作好了,接下來咱們將給park
添加個圖片。 你不須要添加不少代碼,就能夠添加一個帶mask、border、shadow
的圖片。
添加一張圖片到asset catalog
中。 在Resource
文件夾中找到turtlerock.png
圖片,而後把它拖拽到asset catalog中。
選擇File > New > File
打開模版選擇面板。在 User Interface
區域,選擇 SwiftUI View->Next
,命名爲CircleImage.swift
。
把Text
構建方法替換成Image
。
import SwiftUI
struct CircleImage: View {
var body: some View {
Image("turtlerock")
}
}
struct CircleImage_Preview: PreviewProvider {
static var previews: some View {
CircleImage()
}
}
複製代碼
調用.clipShape(Circle())
方法,建立圓形視圖。
再建立一個圓圈,用灰色進行填充。並將它做爲image
的border
。
import SwiftUI
struct CircleImage: View {
var body: some View {
Image("turtlerock")
.clipShape(Circle())
.overlay(
Circle().stroke(Color.gray, lineWidth: 4))
}
}
struct CircleImage_Preview: PreviewProvider {
static var previews: some View {
CircleImage()
}
}
複製代碼
添加陰影。
將邊框顏色更改成白色。
import SwiftUI
struct CircleImage: View {
var body: some View {
Image("turtlerock")
.clipShape(Circle())
.overlay(
Circle().stroke(Color.white, lineWidth: 4))
.shadow(radius: 10)
}
}
struct CircleImage_Preview: PreviewProvider {
static var previews: some View {
CircleImage()
}
}
複製代碼
如今咱們須要建立一個地圖視圖。你能夠MapKit
中的MKMapView
類來展現渲染地圖界面。 在SwiftUI
中要使用UIView
或者其子類,你須要讓你的view
遵循UIViewRepresentable協議
。SwiftUI
在WatchKit
和AppKit
一樣聲明瞭相似的協議
建立新的SwiftUI View
來展現MKMapView
。 File > New > File
,而後建立MapView.swift
引入MapKit
頭文件,而且讓MapView
遵循UIViewRepresentable
協議。
UIViewRepresentable
協議有兩個協議方法須要實現。第一是UIView(context:)
來建立MKMapView
。第二個updateUIView(_:context:)
來更新view
。 把body
屬性幹掉,而後UIView(context:)
協議方法來建立MKMapView
。
import SwiftUI
import MapKit
struct MapView: UIViewRepresentable {
func makeUIView(context: Context) -> MKMapView {
MKMapView(frame: .zero)
}
}
struct MapView_Preview: PreviewProvider {
static var previews: some View {
MapView()
}
}
複製代碼
實現updateUIView(_:context:)
協議方法,來更新view
(設置地圖經緯度等)。
func updateUIView(_ view: MKMapView, context: Context) {
let coordinate = CLLocationCoordinate2D(
latitude: 34.011286, longitude: -116.166868)
let span = MKCoordinateSpan(latitudeDelta: 2.0, longitudeDelta: 2.0)
let region = MKCoordinateRegion(center: coordinate, span: span)
view.setRegion(region, animated: true)
}
複製代碼
當在靜態模式下進行預覽的時候,Xcode
只能渲染SwiftUI
視圖控件。由於MKMapView
是UIView子類
,因此你須要把模式切換成live模式才能正常預覽。 點擊Live Preview
切換預覽模式。
如今咱們已經把全部子控件定義實現好了。 利用咱們現有的工具,咱們能夠把這些子控件組合起來,造成完整的landmarks詳情界面。
在工程導航區,選擇ContentView.swift
文件。
在這三個text view
控件外面,再嵌入一個VStack
視圖。
struct ContentView: View {
var body: some View {
VStack {
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
HStack(alignment: .top) {
Text("Joshua Tree National Park")
.font(.subheadline)
Spacer()
Text("California")
.font(.subheadline)
}
}
.padding()
}
}
}
複製代碼
將你自定義的MapView
放在stack
的上面。設置MapView
的frame
。 若是你只設置了Mapview
的高度,那麼MapView
會自動設置其寬度來適應父視圖。因此MapView
會充滿寬度區域。
struct ContentView: View {
var body: some View {
VStack {
MapView()
.frame(height: 300)
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
HStack(alignment: .top) {
Text("Joshua Tree National Park")
.font(.subheadline)
Spacer()
Text("California")
.font(.subheadline)
}
}
.padding()
}
}
}
複製代碼
點擊Live Preview
來預覽效果。 預覽狀態下,你能夠繼續編寫view
的代碼,Live Preview
會實時更新視圖。
將CircleImage
添加到stack
上面。
struct ContentView: View {
var body: some View {
VStack {
MapView()
.frame(height: 300)
CircleImage()
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
HStack(alignment: .top) {
Text("Joshua Tree National Park")
.font(.subheadline)
Spacer()
Text("California")
.font(.subheadline)
}
}
.padding()
}
}
}
複製代碼
調整一下Image
的偏移。
在VStack
的底部添加spacer
佔位。
最後設置下 edgesIgnoringSafeArea(.top) 。
總體寫下來,就是感受很簡單,很舒服.更加快速的面向開發,此時此刻還有誰! Swift 寫天寫地寫世界,千秋萬載,一統江湖