前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从零开始的 Swift UI (一)

从零开始的 Swift UI (一)

作者头像
Innei
发布2021-12-28 11:03:13
1.4K0
发布2021-12-28 11:03:13
举报
文章被收录于专栏:静之森

注: 本文编写时,使用 Xcode 12.3、Swift 5.3.2 来构建 App

入门 Swift UI 已经有一段时间了,但是却一直没有写过什么练手项目,虽然之前跟着 Hackingwithswift 上找着写过几个 Demo。突然打算自己独立写一个练手项目,因为是练手项目,所以布局和功能上也很简单,App 的类型大概和 TODO 类似。

https://cdn.jsdelivr.net/gh/Innei/img-bed@master/uPic/WCXU9K.png
https://cdn.jsdelivr.net/gh/Innei/img-bed@master/uPic/WCXU9K.png

准备

打开 Xcode 新建一个项目在此不再展开。在左侧文件树中打开 ContentView.swift,这是 View 的入口文件。你可以看到如下代码。

swift

代码语言:javascript
复制
1import SwiftUI
2
3struct ContentView: View {
4    var body: some View {
5        Text("Hello, world!")
6            .padding()
7    }
8}
9
10struct ContentView_Previews: PreviewProvider {
11    static var previews: some View {
12        ContentView()
13    }
14}

COPY

在 Swift UI 2.0 中,UI 主入口文件从复杂的 AppDelegate.swiftSceneDelegate.swift 转变为仅仅只有几行的 xxApp.swift,得益于 Swift 5.3 加入的 @main 关键字

swift

代码语言:javascript
复制
1import SwiftUI
2
3@main
4struct MeetApp: App {
5    var body: some Scene {
6        WindowGroup {
7            ContentView()
8        }
9    }
10}

COPY

布局

HomeView

首先新建一个 View,Command + N 选择 SwiftUI View,命名为 HomeView.swift。将 HomeView 修改为如下代码。

swift

代码语言:javascript
复制
1struct HomeView: View {
2    var body: some View {
3        VStack {
4            Text("我不去想,是否能够成功 ,既然选择了远方 ,便只顾风雨兼程。")
5                .foregroundColor(.blue)
6                .padding(.vertical)
7            
8            Text("hasty")
9        }.padding()
10    }
11}

COPY

1609116435368
1609116435368

接下来,绘制圆形 Button。在 Swift UI 中绘制图形十分简单,Swift UI 中内置了 Circle 组件,只要使用 ZStack 和 Circle 结合,很容易编写这个组件。

swift

代码语言:javascript
复制
1struct CircleButtonShape: View {
2    var systemImage: String
3    var color: Color = .pink
4    var body: some View {
5        ZStack {
6            Circle()
7                .fill(color)
8                .frame(width: 50, height: 50, alignment: .center)
9                .shadow(radius: 3)
10            Image(systemName: systemImage).foregroundColor(.white)
11        }
12    }
13}

COPY

这个组件绘制了整个图形,其中 Image 接收一个 SFSymbol 字符串。SF Symbols 可以在

这里下载

。绘制完了图形接下来需要在 View 中使用这个图形,并定位到对应的地点。

在 Swift UI 中,可以使用 ZStack 结合 .postion 定位到指定地点。为了获取到整个视窗的长宽,还需要 GeometryReader 去读取子 View 的长宽。在根 View 包裹可以获取到设备的长宽。

swift

代码语言:javascript
复制
1     GeometryReader { reader in
2            ZStack {
3                VStack {
4                    Text("我不去想,是否能够成功 ,既然选择了远方 ,便只顾风雨兼程。")
5                        .foregroundColor(.blue)
6                        .padding(.vertical)
7
8                    HStack {
9                        Spacer()
10
11                        Text("hasty")
12                    }
13                }.padding()
14
15                Button(action: {
16                    // TODO:
17                }, label: {
18                    CircleButtonShape(systemImage: "arrow.clockwise")
19                })
20                .position(x: reader.size.width - 50, y: reader.size.height - 50)
21
22            }
23        }

COPY

1609117208574
1609117208574

接下来绘制底部的 ActionView。包含两个 Icon。

swift

代码语言:javascript
复制
1struct ActionView: View {
2    @State var liked = false
3
4    var body: some View {
5        HStack(spacing: 20) {
6            Button(action: {
7            }, label: {
8                Image(systemName: liked ? "suit.heart.fill" : "suit.heart")
9                    .foregroundColor(liked ? .red : .primary)
10                    .font(.custom("icon", size: 28))
11            })
12            Button(action: {
13            }, label: {
14                Image(systemName: "square.and.arrow.up")
15                    .font(.custom("icon", size: 28))
16                    .foregroundColor(.primary)
17            })
18        }
19    }
20}

COPY

在 HomeView 中 ZStack 末尾添加。

swift

代码语言:javascript
复制
1ActionView().offset(x: 0, y: reader.size.height / 2 - 50)

COPY

可以看到如图。

1609117544917
1609117544917

这里使用了 .offset 而不是 .position 去定位,是因为使用 position 去定位会丢失 width: 100% ,可以理解为 CSS 中 block 使用 absolute 之后变成了 inline-block, 而使用 .offset 只是relative 中的定位。

TabView

接下来,绘制底部 Tabbar。在 Swift UI 中使用默认的 Tabbar 极为简单。只需要使用 TabView 即可。

xxApp.swift (为你的 project_nameApp.swift,比如我的 Project 为 Meet,则为 MeetApp.swift) 中增加 TabView

swift

代码语言:javascript
复制
1struct MeetApp: App {
2    var body: some Scene {
3        WindowGroup {
4            TabView {
5                ContentView().tabItem { Label("遇见", systemImage: "circle") }
6            }
7        }
8    }
9}

COPY

TabView 中每个 View 都会在底部 tab 中存在一个 Item,使用 .tabItem 定义这个 item 的文字和 image。有且只有一个 text 和 image。我们再新建一个 SwiftUI View 文件,命名为 LikeView.swift 。在 MeetApp.swift 中增加一个 View。

swift

代码语言:javascript
复制
1 TabView(selection: $activeTabIndex) {
2                ContentView().tabItem {
3                    Label("遇见", systemImage: "largecircle.fill.circle")
4                }
5
6                LikeView().tabItem {
7                    Label("喜欢", systemImage: "heart.circle.fill")
8                }
9            }
10            .accentColor(.pink) // 修改默认主题色

COPY

然后我们给 tabItem 增加 tag,让 Swift UI 知道当前选定的 tab 是哪个。如果被选中,修改为 Solid 的 Icon。当然我们可以使用 @State.onTapGesture 实现。

swift

代码语言:javascript
复制
1@main
2struct MeetApp: App {
3    @State var activeTabIndex = 0
4  
5    var body: some Scene {
6        return WindowGroup {
7            TabView(selection: $activeTabIndex) {
8                HomeView().tabItem {
9                    Label("遇见", systemImage: activeTabIndex != 0 ? "circle" : "largecircle.fill.circle")
10                        .onTapGesture {
11                            activeTabIndex = 0
12                        }
13                }
14                .tag(0)
15
16                LikeView().tabItem {
17                    Label("喜欢", systemImage: activeTabIndex != 1 ? "heart.circle" : "heart.circle.fill")
18                        .onTapGesture {
19                            activeTabIndex = 1
20                        }
21                }
22                .tag(1)
23            }
24            .accentColor(.pink)
25        }
26    }
27}

COPY

注意:.tag 是不可或缺的。否则无效。

大功告成!

1609118401778
1609118401778

下一篇文章,将构建数据层。

(未待完续)

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-12-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 准备
  • 布局
    • HomeView
      • TabView
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档