prefacio
En este capítulo, aprenderá a crear Search
búsquedas para búsquedas de lista y TabView
navegación inferior.
En el capítulo anterior , completamos una ColourAtla
aplicación de tarjeta de color simple y luego continuamos mejorando App
el contenido relacionado.
Barra de búsqueda SearchBar
La primera es la SearchBar
barra de búsqueda.La función de la barra de búsqueda es recuperar el contenido de la lista para encontrar la carta de color que necesitamos.
Usamos el TextField
cuadro de entrada para construir SearchBar
la barra de búsqueda, comenzamos declarando una variable para almacenar nuestro contenido de búsqueda. Ejemplo:
@State var search = ""
Luego SearchBar
diseñe la barra de búsqueda. Ejemplo:
// 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)
}
En el código anterior, construimos una nueva vista SearchBarView
, usamos el TextField
cuadro de entrada como la barra de búsqueda, vinculamos el search
contenido y luego usamos modificadores para refinar el SearchBar
estilo de la barra de búsqueda. Reemplacemos el original para CardTitleView
ver el efecto:
método de búsqueda
Para implementar la interacción de buscar nombres de colores , necesitamos proporcionar un método para buscar las muestras de color en la lista. Ejemplo:
// 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
}
}
}
}
En el código anterior, hemos creado un método para buscar color Al buscar el parámetro de valor de color de la tarjeta en la matriz de tarjetas de color de searchColor
acuerdo con el contenido del texto de búsqueda search
, si la coincidencia es exitosa , encontraremos y mostraremos el color en la matriz de tarjetas de color.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加载动画
加载样式
Anteriormente, ProgressView
la usábamos como animación predeterminada en la carga, como una ColourAtla
tarjeta de color App
, y ProgressView
la usábamos como animación de carga, que no era lo suficientemente elegante .
Podemos construir una animación de carga usando SwiftUI
los modificadores oficiales rotationEffect
, creando primero un nuevo SwiftUI
archivo llamado LoadingView
.
Primero declare una variable para almacenar el estado de rotación, luego construya una imagen rotada 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))
}
}
En el código anterior, Image
construimos un ícono cargado usando el rotationEffect
modificador show
y lo rotamos según el estado.
método de carga
Para hacer que el ícono de carga gire , creamos un método doAnimation
que alterna show
el estado cada 1 segundo .
func doAnimation() {
withAnimation(Animation.easeInOut(duration: 1).repeatForever(autoreverses: true)) {
show.toggle()
}
}
Cuando haya terminado, el método que Image
llamamos al presentar doAnimation
.
Finalmente, ContentView
reemplazamos LoadingView
el original con ProgressView
, y luego verificamos el efecto:
Vista previa del proyecto
¡Ven y pruébalo!
Si esta columna es útil para usted, haga clic en Me gusta, comente y siga ~
Estoy participando en el reclutamiento del programa de firma de creadores de la Comunidad Tecnológica de Nuggets, haga clic en el enlace para registrarse y enviar .