기능 구현 #5
유저 검색 기능
유저 검색 기능
| SearchBar
SwiftUI에서도 SearchBar를 제공하지만 List나 NavigationView 등 특정 View만 지원하므로
심미적인 목적이나 구현 스타일에 따라 새롭게 구성할 수 있어야 한다.
struct SearchBar: View {
@Binding var text: String
}
SearchBar는 사용자에게서 검색어를 입력 받고, 이를 ExploreView에서 사용할 수 있어야 한다.
따라서 상위 View에서 선언한 변수를 사용할 수 있도록 Binding으로 변수를 하나 선언한다.
struct SearchBar: View {
@Binding var text: String
var body: some View {
TextField("Search...", text: $text)
.padding(8)
.padding(.horizontal, 24)
.background(Color(.systemGray6))
.cornerRadius(8)
.padding(.horizontal, 4)
}
}
사용자가 검색어를 입력할 수 있도록 TextField를 하나 구성했다.
struct SearchBar: View {
@Binding var text: String
var body: some View {
TextField("Search...", text: $text)
.padding(8)
.padding(.horizontal, 24)
.background(Color(.systemGray6))
.cornerRadius(8)
.overlay {
Image(systemName: "magnifyingglass")
.foregroundColor(.gray)
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
.padding(.leading, 8)
}
.padding(.horizontal, 4)
}
}
검색창임을 확실히 할 수 있도록 overlay를 사용해 돋보기 아이콘을 표시했다.
유저 검색 기능
| ExploreView
struct ExploreView: View {
@ObservedObject var viewModel = ExploreViewModel()
@State private var searchText = ""
var body: some View {
VStack {
SearchBar(text: $searchText)
.padding()
ScrollView {
LazyVStack {
ForEach(viewModel.users) { user in
NavigationLink {
ProfileView(user: user)
} label: {
UserRowView(user: user)
}
}
}
}
}
.navigationTitle("Explore")
.navigationBarTitleDisplayMode(.inline)
}
}
SearchBar에 Binding으로 전달할 State 변수를 하나 선언하고,
ScrollView 위에 표시되도록 SearchBar를 배치한다.
이렇게 ExploreView의 상단에 SearchBar가 생겼다.
유저 검색 기능
| ExploreViewModel
class ExploreViewModel: ObservableObject {
@Published var users = [User]()
@Published var searchText = ""
var searchableUsers: [User] {
if searchText.isEmpty {
return users
본격적으로 검색 기능을 구현하기 위해 검색어를 받아 올 속성을 하나 선언한다.
Published 변수인 searchText는 이후 SearchBar에 Binding으로 전달 될 변수이다.
var searchableUsers: [User] {
if searchText.isEmpty {
return users
} else {
}
}
만약 searchText가 비어있다면 전체 사용자 목록을 표시할 수 있도록 전체 사용자 배열인 users를 반환한다.
var searchableUsers: [User] {
if searchText.isEmpty {
return users
} else {
let lowercasedQuery = searchText.lowercased()
return users.filter({
$0.username.contains(lowercasedQuery) || $0.fullname.lowercased().contains(lowercasedQuery)
})
}
}
검색어가 존재한다면 검색어를 소문자로 변환한 뒤, 전체 사용자 배열인 users 배열을 검색어로 필터링해, 이를 반환한다.
이렇게 반환되는 배열의 이름은 searchableUsers 이다.
유저 검색 기능
| ExploreView
struct ExploreView: View {
@ObservedObject var viewModel = ExploreViewModel()
var body: some View {
VStack {
SearchBar(text: $viewModel.searchText)
.padding()
ScrollView {
LazyVStack {
ForEach(viewModel.searchableUsers) { user in
NavigationLink {
ProfileView(user: user)
} label: {
UserRowView(user: user)
}
}
}
}
}
.navigationTitle("Explore")
.navigationBarTitleDisplayMode(.inline)
}
}
ExploreViewModel에 검색 기능을 위한 Published 변수 searchText가 생겼으므로 ExploreView의 임시 변수는 삭제했다.
SearchBar(text: $viewModel.searchText)
.padding()
SearchBar의 파라미터로 viewModel의 searchText를 Binding으로 전달하고,
ForEach(viewModel.searchableUsers) { user in
NavigationLink {
ProfileView(user: user)
} label: {
UserRowView(user: user)
}
}
표시할 사용자의 목록은 searchableUsers로 변경한다.
동작하는 모습은 위와 같다.
'프로젝트 > Twitter Clone App (w∕Firebase)' 카테고리의 다른 글
19. 기능 구현 #7 (0) | 2023.01.14 |
---|---|
18. 기능 구현 #6 (0) | 2023.01.13 |
16. 코드 가독성 개선 (0) | 2023.01.11 |
15. 기능구현 #4 (0) | 2023.01.11 |
14. 버그 수정 #1 (0) | 2023.01.11 |