foreword
In this chapter, you'll learn to build Search
searches for list searches and TabView
bottom navigation.
In the previous chapter , we completed a simple ColourAtla
color card App , and then we continue to improve App
the related content.
SearchBar search bar
The first is the SearchBar
search bar. The function of the search bar is to retrieve the content of the list to find the color card we need.
We use the TextField
input box to build SearchBar
the search bar, we start by declaring a variable to store our search content. Example:
@State var search = ""
Then SearchBar
style the search bar. Example:
// MARK: 搜索
private var SearchBarView: some View {
TextField("搜索颜色值", text: $search)
.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)
}
In the above code, we build a new view SearchBarView
, use the TextField
input box as the search bar, bind the search
content, and then use modifiers to refine the SearchBar
style of the search bar. Let's replace the original to CardTitleView
see the effect:
search method
In order to implement the interaction of searching for color names , we need to provide a method to search the color swatches in the list. Example:
// MARK: 搜索颜色方法
func searchColor() {
let query = search.lowercased()
DispatchQueue.global(qos: .background).async {
let filter = cardItems.filter { $0.cardColorRBG.lowercased().contains(query) }
DispatchQueue.main.async {
withAnimation(.spring()) {
self.cardItems = filter
}
}
}
}
In the above code, we have created a method to search for color . By searching for the color value parameter of the card in the color card array searchColor
according to the search text content search
, if the match is successful , we will find and display the color in the color card array.cardItems
cardColorRBG
cardItems
我们在SearchBarView
视图中,当我们TextField
输入框内容变化时调用这个方法。示例:
.onChange(of: search) { _ in
if search != "" {
searchColor()
} else {
search = ""
getColors()
}
}
上述代码中,我们在TextField
输入框搜索内容search
变量改变时,且search
输入内容不为空时调用searchColor
搜索颜色的方法,当search
输入内容为空时,又重新调用getColors
获取颜色的方法,这样,我们就实现了搜索颜色值的交互。
搜索栏切换
接下来,我们来实现标题栏和搜索栏的切换。
我们尝试在标题栏右侧加入一个搜索图标,点击搜索图标切换到搜索栏,在搜索栏输入框右侧也增加一个取消按钮,点击取消又回到标题栏中。
先声明一个存储变量showSearchBar
用于判断切换状态。
@State var showSearchBar = false
然后构建搜索按钮的样式和取消按钮的样式。示例:
// MARK: 搜索icon
private var SearchButtonView: some View {
Button(action: {
withAnimation(.easeOut) {
showSearchBar.toggle()
}
}, label: {
Image(systemName: "magnifyingglass")
.font(.system(size: 20, weight: .bold))
.foregroundColor(.gray)
})
}
// MARK: 取消按钮
private var CloseButtonView: some View {
Button(action: {
withAnimation(.easeOut) {
search = ""
getColors()
showSearchBar.toggle()
}
}, label: {
Text("取消")
.foregroundColor(.gray)
})
}
上述代码中,我们创建了两个视图SearchButtonView
和CloseButtonView。
在SearchButtonView
视图中,我们使用系统搜索图标做一个搜索按钮操作,点击时更改showSearchBar
的状态。
在CloseButtonView
视图中,我们使用文字按钮做一个取消按钮的操作,点击时清空输入框的内容search
,并且更改showSearchBar
的状态,同时调用getColors
获取颜色的方法。
完成这些后,我们进行样式的组装,示例:
// MARK: 搜索切换
private var SwitchSearchBar: some View {
HStack(spacing: 20) {
if showSearchBar {
SearchBarView
CloseButtonView
} else {
CardTitleView
Spacer()
SearchButtonView
}
}
.padding(.top, 20)
.padding(.bottom, 10)
.padding(.horizontal)
.zIndex(1)
}
上述代码中,我们构建了一个新的视图SwitchSearchBar
。
在SwitchSearchBar
视图中,我们根据showSearchBar
的状态切换展示搜索栏还是标题栏的内容,并把SwitchSearchBar
视图在ContentView
主视图中呈现。
我们预览下效果:
TabView底部导航
我们创建一个新的SwiftUI
文件,命名为TabberView
。
struct TabberView: View {
@State private var selectedTab = 0
var body: some View {
TabView(selection: $selectedTab) {
ContentView()
.tabItem {
if self.selectedTab == 0 {
Image(systemName: "house")
} else {
Image(systemName: "house.fill")
}
Text("首页")
}
.tag(0)
Text("我的")
.tabItem {
if self.selectedTab == 1 {
Image(systemName: "person")
} else {
Image(systemName: "person.fill")
}
Text("我的")
}
.tag(1)
}
.accentColor(Color.Hex(0x409EFF))
}
}
上述代码中,我们使用TabView
来构建底部导航。
我们声明一个变量selectedTab
来跟踪当前选中的是哪一个菜单,然后在TabView
中绑定selectedTab
的值。我们使用tabItem
修饰符来显示当前菜单的内容,并且根据 selectedTab
选中的状态修饰底部菜单的图标和文字。
最后我们给选中的菜单加上accentColor
选中颜色。
我们预览下效果:
我们把之前章节完成的MineView
我的视图也换到TabView
底部菜单中,预览看下效果:
LoadingView加载动画
加载样式
Previously we used it ProgressView
as the default animation in loading, as a ColourAtla
color card App
, and used it ProgressView
as the loading animation, which was not elegant enough .
We can build a loading animation using SwiftUI
the official rotationEffect
modifiers, by first creating a new SwiftUI
file named LoadingView
.
First declare a variable to store the rotation state, then build a rotated picture icon
.
import SwiftUI
struct LoadingView: View {
@State var show: Bool = false
var body: some View {
Image(systemName: "sun.min.fill")
.resizable()
.foregroundColor(Color.Hex(0xFAD0C4))
.aspectRatio(contentMode: .fit)
.frame(width: 60, height: 60)
.rotationEffect(.degrees(show ? 360 : 0))
}
}
In the above code, we Image
build a loaded icon using the rotationEffect
modifier show
and rotate it according to the state.
Load method
To make the loading icon rotate , we create a method doAnimation
that toggles show
the state every 1 second .
func doAnimation() {
withAnimation(Animation.easeInOut(duration: 1).repeatForever(autoreverses: true)) {
show.toggle()
}
}
When done, the method we Image
call when presenting doAnimation
.
Finally, we ContentView
are replacing LoadingView
the original with ProgressView
, and then check the effect:
Project preview
Come and try it!
If this column is helpful to you, please like, comment, and follow~
I am participating in the recruitment of the creator signing program of the Nuggets Technology Community, click the link to register and submit .