今日职言:能够享受最好的,也要能够接受最差的。
在本章中,你将学会如何使用TextField
输入框构建一个SearchBar搜索栏。
在很多App中,我们都可以看到SearchBar
搜索栏的身影,比如用来搜索某条资讯,搜索某个联系人,亦或者搜索某个功能……
那么这一章节,我们就来学习下如何创建一个简答的SearchBar
搜索栏。
那么,我们开始吧。
首先,创建一个新项目,命名为SwiftUISearchBar
。
UI部分
我们看到SearchBar
搜索栏的样式其实就是一个TextField
输入框,我们在里面输入文字作为搜索条件,TextField
输入框输入的内容再关联SearchBar
组件,达到搜索的目的。
我们构建一个简单的SearchBarView
搜索栏视图。
// SearchBarView搜索栏视图
struct SearchBarView: View {
@Binding var text: String
@State private var offset: CGFloat = .zero // 使用.animation防止报错,iOS15的特性
var body: some View {
TextField("搜你想看的", text: $text)
.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)
)
.padding(.horizontal, 10)
}
}
逻辑部分
然后,我们思考下SearchBarView
搜索栏的逻辑。
当我们SearchBarView
搜索栏没有输入内容时,显示的是“搜你想看的
”文字,那么当我们在TextField
输入内容的时候, 应该要删除placehoder
文字。
我们可以定义一个TextField
输入框是否正在编辑isEditing
的状态,通过isEditing
是否处于编辑状态来判断。
@State private var isEditing = false
当我们点击TextField
输入框输入的时候,isEditing
状态为true
,同时TextField
输入框内部右侧会显示一个清除图标,点击清除图标可以清空我们输入的内容。
而且清除图标和TextField
输入框是HStack
横向排布,我们完成下交互逻辑。
//点击时
.onTapGesture {
self.isEditing = true
//编辑时显示清除按钮
if isEditing {
Button(action: {
self.text = ""
}) {
Image(systemName: "multiply.circle.fill")
.foregroundColor(.gray)
.padding(.trailing, 8)
}
}
另外,当我们isEditing
是否处于编辑状态时,SearchBarView
搜索栏应该右边空出一个位置,显示搜索文字按钮,点击搜索时,isEditing
恢复到初始false
状态。
搜索按钮和整个TextField
输入框也是HStack
横向排布。
// 搜索按钮
if isEditing {
Button(action: {
self.isEditing = false
self.text = ""
}) {
Text("搜索")
}
.padding(.trailing, 10)
.transition(.move(edge: .trailing))
.animation(.default, value: offset)
}
我们在模拟器中预览效果。
但这里我们发现一个问题,当我们点击“搜索
”按钮的时候,虽然SearchBarView
搜索栏恢复初始状态了,但是keyboard
键盘没有自动收下去。
我们需要额外添加一个收起keyboard
键盘的方法,代码如下:
// 收起键盘
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
这样,我们就实现了点击“搜索
”时,清空TextField
输入框文字,恢复到初始状态
,并且收起keyboard
键盘。
完整代码如下:
import SwiftUI
struct ContentView: View {
@State var text: String = ""
var body: some View {
VStack {
SearchBarView(text: $text)
.padding()
Spacer()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
// SearchBarView搜索栏视图
struct SearchBarView: View {
@Binding var text: String
@State private var isEditing = false
@State private var offset: CGFloat = .zero //使用.animation防止报错,iOS15的特性
var body: some View {
HStack {
TextField("搜你想看的", text: $text)
.padding(7)
.padding(.horizontal, 25)
.background(Color(.systemGray6))
.cornerRadius(8)
.overlay(
HStack {
Image(systemName: "magnifyingglass")
.foregroundColor(.gray)
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
.padding(.leading, 8)
// 编辑时显示清除按钮
if isEditing {
Button(action: {
self.text = ""
}) {
Image(systemName: "multiply.circle.fill")
.foregroundColor(.gray)
.padding(.trailing, 8)
}
}
}
)
.padding(.horizontal, 10)
// 点击时
.onTapGesture {
self.isEditing = true
}
// 搜索按钮
if isEditing {
Button(action: {
self.isEditing = false
self.text = ""
// 收起键盘
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}) {
Text("搜索")
}
.padding(.trailing, 10)
.transition(.move(edge: .trailing))
.animation(.default, value: offset)
}
}
}
}
快来动手试试吧!
如果本专栏对你有帮助,不妨点赞、评论、关注~