SwiftUI实战-仿写微信App(三)

2,118 阅读2分钟

这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战

前文

一、目标

image1.jpeg

实现通讯录的页面。

二、思路

由于篇幅太长,本节只讲述搜索栏。

这个搜索栏其实是一个按钮,通过点击它会打开一个新的搜索页。

所以这个功能,分成2步。

  • 第一步,画这个搜索框框,通过点击它打开新页面。
  • 第二步,实现这个搜索新页面,增加真的搜索栏。

三、搜索框

首先,搜索框可以分成一个矩形HStack(文字加图标)的结合体,所以使用ZStack结合二者即可。

ScrollView{
    ZStack{
        
        Rectangle().fill().frame(height: 50).foregroundColor(.white).cornerRadius(5).padding(12.5)
        
        HStack{
            Image(systemName: "magnifyingglass")
            Text("搜索")
        }.foregroundColor(Color(red: 188/255, green: 188/255, blue: 188/255))
        
    }
}.background(Color(red: 237/255, green: 237/255, blue: 237/255))
  • 使用Rectangle设置矩形
  • cornerRadius设置圆角
  • Color(red: 188/255, green: 188/255, blue: 188/255)可以设置RGB色彩模式。不过通过取色器获取出来的值要除以255才是真正对应的值。

image.png

接下来实现点击打开新页面,但是实际操作微信会发现,打开的动画并非左右滑动打开,而是类似打开全屏的动画模式。

SwiftUI中提供了这种打开方式,只需要给搜索框增加一个fullScreenCover属性。

.fullScreenCover(isPresented: $searchFullPagePresented, content: {
     Button(action: {
        searchFullPagePresented = false
    }, label: {
        Text("back")
    })
}).onTapGesture {
    searchFullPagePresented = true
}
  • 其中isPresented用来控制页面的打开关闭事件。
  • content包裹的就是全屏页的内容。
  • onTapGesture增加触屏点击事件,通过修改searchFullPagePresented=true来达成打开全屏页的事件。
  • Button是全屏页中的返回按钮,点击之后返回通讯录。

202108032128.gif

四、搜索全屏页

image.png

这里的难点可以分为2个。

  • 1是这个矩形搜索栏的实现
  • 2是取消按钮返回通讯录。

返回按钮,上一步中已经实现,通过searchFullPagePresented=false来实现,所以暂且不谈。

只看第一步,整个搜索栏可以拆分一下。

image.png

  • 创建一个SearchFullScreenView.swift把全屏页的内容抽象出来。
  • 整个矩形是一个ZStackRectangle即可实现
  • 红色的是一个放大镜图标
  • 蓝色的是输入框TextField
  • 绿色也是一个语音图标
  • 最后通过HStack连接起来

所以代码如下

struct SearchFullScreenView: View {
    
    @State var searchText: String = ""
    
    @Binding var searchFullPagePresented: Bool
    
    var body: some View {
        ScrollView{
            HStack{
                ZStack{
                    Rectangle().fill().frame(height: 50).foregroundColor(.white).cornerRadius(5).padding(12.5)
                    
                    HStack{
                        
                        Image(systemName: "magnifyingglass")
                        TextField("搜索", text: $searchText)
                        Image(systemName: "mic")
                        
                    }.padding()
                }
                Button("取消") {
                    searchFullPagePresented = false
                }.padding(.trailing)
            }.background(Color(red: 237/255, green: 237/255, blue: 237/255))
            
        }
        
    }
}
  • 这里使用双向绑定子组件@Binding父组件@State,通过控制searchFullPagePresentedtruefalse来实现页面的打开与关闭。

五、常用搜索九宫格

SwiftUI中提供了LazyVGrid来实现纵向布局的九宫格网格布局。

let columns: [GridItem] = Array(repeating: .init(.flexible()), count: 3)
LazyVGrid(columns: columns) {
    ForEach((0..<commonSearchFilter.count), id: \.self) {index in

        Text("\(commonSearchFilter[index])").font(.callout).padding(.bottom).foregroundColor(.blue)

    }
}.font(.largeTitle)
            
  • LazyVGrid接收一个columns参数布局设置
  • 通过repeating指定.fixed(100)固定宽度还是.flexible弹性宽度
  • count指定网格数

202108032216.gif

附:代码地址

gitee.com/dkwingcn/we…

相关文章

SwiftUI实战-仿写微信App(四)