Swift编程Swift开发进阶SwiftUI

WWDC - SwiftUI - 初恋般的感觉

2019-06-22  本文已影响101人  Cooci_和谐学习_不急不躁

*SwiftUI is a modern way to declare user interfaces for any Apple platform. Create beautiful, dynamic apps faster than ever before.

一种牛逼的更加快速,更加漂亮的用户界面的方法

创建和组合视图

创建一个使用SwiftUI的新Xcode项目。浏览画布、预览和SwiftUI模板代码。

要在Xcode中预览画布上的视图并与之交互,请确保您的Mac运行的是macOS 10.15 beta版

macOS 10.15 beta版下载地址
Xcode 11下载地址

第一步

第二步

第三步

点击之后你就会感觉发现了新东西咯:

默认情况下,SwiftUI视图文件声明两个结构。

现在我们来玩玩预览:

如果画布没有展示出来,可以通过 Editor > Editor and Canvas 显示出来。

第四步

把Hello World更改为Hello SwiftUI!
当你修改文案后,SwiftUI会自动更新视图。


自定义Text View

你有两种方式来自定义TextView

当你构建Landmarks的时候,你可以运用任何一个编辑器来进行编码工作:直接修改源代码、通过画布、通过inspector view检查器。代码并不会关心你用什么工具,它始终能够保持最新状态

接下来,你将通过inspector来自定义Text View

第一步

第二步

通过inspector检查器修改Text文本框的属性。

第三步

第四步

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 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()
    }
}

第八步


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 写天写地写世界,千秋万载,一统江湖

上一篇下一篇

猜你喜欢

热点阅读