WWDC - SwiftUI - 初戀般的感受

*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

第一步

  • 打開 Xcode->Create a new Xcode project,或者經過File > New > Project 來建立工程。

第二步

  • 在模版選擇區域,選擇 iOS->Single View App->Next 。

第三步

  • 輸入項目名稱 LGSwiftUIDemo->勾選Use SwiftUI->Next 保存。 記得必定要選擇語言:Swift 而後勾選 Use SwiftUI

點擊以後你就會感受發現了新東西咯:app

  • 左邊沒有了ViewController 多了sceneDelegate和ContentView
  • 中間代碼樣式不同了
  • 右邊多出一塊預顯示欄,很牛逼

默認狀況下,SwiftUI視圖文件聲明兩個結構。框架

  • 第一個結構符合視圖協議,描述了視圖的內容和佈局。
  • 第二個結構聲明瞭該視圖的預覽。

如今咱們來玩玩預覽:編輯器

若是畫布沒有展現出來,能夠經過 Editor > Editor and Canvas 顯示出來。ide

第四步

把Hello World更改成Hello SwiftUI! 當你修改文案後,SwiftUI會自動更新視圖。 工具

自定義Text View

你有兩種方式來自定義TextView佈局

  • 第一種方式是直接修改view代碼
  • 第二種方式是經過inspector檢查器來幫助你進行代碼編寫。

當你構建Landmarks的時候,你能夠運用任何一個編輯器來進行編碼工做:直接修改源代碼、經過畫布、經過inspector view檢查器。代碼並不會關心你用什麼工具,它始終可以保持最新狀態

接下來,你將經過inspector來自定義Text 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修改自動更新你的代碼。

利用Stacks組合視圖

咱們建立了一個文本框用來顯示landmark的詳情信息,而且把這個文本控件放到頭部。 當咱們建立SwiftUI視圖控件的時候,咱們會把控件的內容、佈局還有一些行爲放在body屬性中;然而body屬性只返回了一個view。你能夠利用stacks嵌入多個view,它能夠垂直嵌入、水平嵌入等。 在這裏,咱們將使用垂直stack來顯示park詳情信息

第一步

Command+點按text初始化方法區域。選擇Embed in VStack

第二步

  • 接下來,咱們將拖拽一個text viewstack中。
  • 點擊+號,打開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())方法,建立圓形視圖。

第五步

再建立一個圓圈,用灰色進行填充。並將它做爲imageborder

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()
    }
}
複製代碼

UIKit和SwiftUI混合使用

如今咱們須要建立一個地圖視圖。你能夠MapKit中的MKMapView類來展現渲染地圖界面。 在SwiftUI中要使用UIView或者其子類,你須要讓你的view遵循UIViewRepresentable協議SwiftUIWatchKitAppKit一樣聲明瞭相似的協議

第一步

建立新的SwiftUI View來展現MKMapViewFile > 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視圖控件。由於MKMapViewUIView子類,因此你須要把模式切換成live模式才能正常預覽。 點擊Live Preview切換預覽模式。

把上面的子控件組合成一個完成的詳情界面

如今咱們已經把全部子控件定義實現好了。 利用咱們現有的工具,咱們能夠把這些子控件組合起來,造成完整的landmarks詳情界面。

image.png

第一步

在工程導航區,選擇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的上面。設置MapViewframe。 若是你只設置了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 寫天寫地寫世界,千秋萬載,一統江湖

相關文章
相關標籤/搜索