diff --git a/DevLog/Resource/Localizable.xcstrings b/DevLog/Resource/Localizable.xcstrings index 252bb80d..89a502fe 100644 --- a/DevLog/Resource/Localizable.xcstrings +++ b/DevLog/Resource/Localizable.xcstrings @@ -6,6 +6,9 @@ }, "%@ 검색" : { + }, + "%@의 제목이나 내용을 검색해 보세요." : { + }, "%lld" : { diff --git a/DevLog/UI/Home/TodoListView.swift b/DevLog/UI/Home/TodoListView.swift index 152e82b1..56f73a80 100644 --- a/DevLog/UI/Home/TodoListView.swift +++ b/DevLog/UI/Home/TodoListView.swift @@ -23,10 +23,10 @@ struct TodoListView: View { } } else { Group { - if viewModel.state.searchText.isEmpty { - todoListContent - } else { + if viewModel.state.isSearching { searchResultsContent + } else { + todoListContent } } .searchable( @@ -34,6 +34,10 @@ struct TodoListView: View { get: { viewModel.state.searchText }, set: { viewModel.send(.setSearchText($0)) } ), + isPresented: Binding( + get: { viewModel.state.isSearching }, + set: { viewModel.send(.setIsSearching($0)) } + ), placement: .navigationBarDrawer(displayMode: .always), prompt: "\(viewModel.state.kind.localizedName) 검색" ) @@ -162,9 +166,8 @@ struct TodoListView: View { .listRowBackground(Color.clear) } .listStyle(.plain) - .refreshable { - viewModel.send(.refresh) - } + .refreshable { viewModel.send(.refresh) } + .scrollDisabled(viewModel.state.todos.isEmpty || viewModel.state.isLoading) if viewModel.state.isLoading { LoadingView() @@ -189,6 +192,7 @@ struct TodoListView: View { ) } + @ViewBuilder private var searchResultsContent: some View { let searchResults = viewModel.state.searchResults let limit = viewModel.searchResultsLimit @@ -196,17 +200,21 @@ struct TodoListView: View { ? searchResults : Array(searchResults.prefix(limit)) - return ScrollView { - LazyVStack(spacing: 0) { - if viewModel.state.isLoading { - LoadingView() - .padding(.top, 40) - } else if searchResults.isEmpty { - Text("검색 결과가 없습니다.") - .foregroundStyle(Color.gray) - .frame(maxWidth: .infinity) - .padding(.top, 40) - } else { + if viewModel.state.searchText.isEmpty { + Text("\(viewModel.state.kind.localizedName)의 제목이나 내용을 검색해 보세요.") + .foregroundStyle(Color.gray) + .frame(maxWidth: .infinity) + } else if viewModel.state.isLoading { + LoadingView() + } else if searchResults.isEmpty { + Spacer() + Text("검색 결과가 없습니다.") + .foregroundStyle(Color.gray) + .frame(maxWidth: .infinity) + Spacer() + } else { + ScrollView { + LazyVStack(spacing: 0) { ForEach(displayedTodos) { todo in Button { router.push(Path.detail(todo.id)) diff --git a/DevLog/UI/Search/SearchView.swift b/DevLog/UI/Search/SearchView.swift index 9e23a2ba..9710eff7 100644 --- a/DevLog/UI/Search/SearchView.swift +++ b/DevLog/UI/Search/SearchView.swift @@ -59,23 +59,25 @@ struct SearchView: View { @ViewBuilder private var searchableContent: some View { - ScrollView { - LazyVStack(alignment: .leading, spacing: 0) { - if viewModel.state.isLoading { - LoadingView() - } else if viewModel.state.searchQuery.isEmpty { - if viewModel.state.recentQueries.isEmpty { - searchInstruction - } else { + Group { + if viewModel.state.isLoading { + LoadingView() + } else if viewModel.state.searchQuery.isEmpty { + if viewModel.state.recentQueries.isEmpty { + searchInstruction + } else { + ScrollView { recentQueries } - } else if viewModel.state.webPages.isEmpty && viewModel.state.todos.isEmpty { - emptySearchResult - } else { + } + } else if viewModel.state.webPages.isEmpty && viewModel.state.todos.isEmpty { + emptySearchResult + } else { + ScrollView { searchResults + .frame(maxWidth: .infinity, alignment: .leading) } } - .frame(maxWidth: .infinity, alignment: .leading) } .searchable( text: Binding(