釋出&選擇釋出,使用SwiftUI搭建一個新建釋出彈窗(上)

語言: CN / TW / HK

theme: smartblue

攜手創作,共同成長!這是我參與「掘金日新計劃 · 8 月更文挑戰」的第23天,點選檢視活動詳情

專案背景

在之前的章節中,我們探討過如果掘金客戶端要做釋出文章功能,那麼入口應該放在那個地方。

當我們確定了入口後,目前掘金Web端支援釋出文章沸點,移動端估計也會同步融合這兩塊功能作為一個入口。

我們再深化一下,當我們點選“釋出”功能入口時,客戶端該如何進行互動?那麼本章中,我們就來完成這個互動頁面。

專案搭建

首先,建立一個新的SwiftUI專案,命名為PublishingView

1.png

頂部導航

我們暫定“釋出”功能的入口在頂部導航右邊,也就是頁面右上角。我們基於當前掘金客戶端的佈局,來構建下整個頂部導航,設計稿示例:

2.png

我們來分析下結構,頂部導航由一個“直播”按鈕入口,一個“搜尋欄”,以及一個“釋出”功能按鈕組成。

對於“搜尋欄”的構建,我們需要宣告一個變數來繫結和儲存輸入的內容;以及當我們點選“釋出”按鈕時會開啟一個彈窗頁面,我們也需要一個變數來儲存開啟的狀態,示例:

@State var searchText = “" @State var showMaskView: Bool = false

然後我們來完成整個頂部導航的樣式,示例:

``` // 搜尋欄 func topBarMenu() -> some View {     HStack(spacing: 15) {

// 直播         Button(action: {         }) {             Image(systemName: "video.square")                 .font(.system(size: 24))                 .foregroundColor(.gray)         }

TextField("搜尋文如秋雨", text: $searchText)             .padding(7)             .padding(.horizontal, 25)             .background(Color(.systemGray6))             .cornerRadius(8)             .overlay(                 Image(systemName: "magnifyingglass")                     .foregroundColor(.gray)                     .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading).padding(.leading, 8)             )

// 新建釋出         Button(action: {             withAnimation {                 self.showMaskView = true             }         }) {             Image(systemName: "plus.circle.fill")                 .font(.system(size: 24))                 .foregroundColor(.blue)         }     }.padding(.horizontal, 15) } ```

上述程式碼中,我們構建了一個新的檢視topBarMenu

我們使用VStack縱向檢視排布了一個“直播”Button按鈕,一個搜尋欄TextField輸入框,一個“釋出”Button按鈕。搜尋欄TextField輸入框的內容繫結我們宣告好的變數searchText,“釋出”Button按鈕點選時,切換showMaskView狀態開啟彈窗。

然後我們在ContentView主檢視中構建樣式,示例:

var body: some View {     VStack {         topBarMenu()         Spacer()     } }

3.png

背景蒙層

當我們點選“釋出“按鈕開啟彈窗時,除了彈窗本身外,彈窗背後還有一個背景蒙層,我們可以單獨構建這個背景蒙層。示例:

``` // MARK: 蒙層 struct MaskView: View {     @Binding var showMaskView: Bool

var body: some View {         VStack {             Spacer()         }         .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)         .background(.black)         .edgesIgnoringSafeArea(.all)         .opacity(0.2)         .onTapGesture {             self.showMaskView = false         }     } } ```

上述程式碼中,我們使用結構體的方式抽離出背景蒙層MaskView

MaskView結構體中,我們使用@Binding方便我們做雙向繫結,然後使用edgesIgnoringSafeArea修飾符構建一個滿屏的頁面,這個頁面背景顏色透明度為0.2的黑色,這樣我們就完成了背景蒙層的設計。

互動方面,當我們點選背景蒙層時,切換showMaskView狀態,以實現關閉彈窗。

我們在ContentView主檢視使用MaskView背景蒙層看看效果,示例:

var body: some View {     ZStack {         VStack {             topBarMenu()             Spacer()         }         if showMaskView {             MaskView(showMaskView: $showMaskView)         }     } }

上述程式碼中,我們通過判斷showMaskView狀態的值,來實現顯示MaskView背景蒙層,點選執行預覽下專案:

4.gif

未完待續

由於彈窗的樣式和互動邏輯較為複雜,這裡將專案分為上下兩章來實現。上篇我們完成頂部導航和背景蒙層的設計,下篇我們來實現下彈窗的彈出、收起、拖動等功能互動。

快來動手試試吧。

如果本專欄對你有幫助,不妨點贊、評論、關注~

「其他文章」