iOS Swift开发:清除搜索框后分页未重置至第一页问题
解决iOS Swift分页搜索时页码未重置的问题
需求逻辑
- 输入查询内容,返回所有匹配结果;若结果超过10条,分页展示(每页10条),支持分页控件切换页面
- 清除/清空搜索框时,分页需重置至第一页(当前页码设为0),为下一次查询做准备
当前问题
浏览过旧查询的分页结果后,清空搜索框再进行新查询,分页未重置到第一页,导致新查询结果从旧的当前页码开始展示,第一页内容被忽略,用户需手动逐页返回才能查看第一页
现有代码
import SwiftUI class DictionaryViewModel: ObservableObject { @Published var filteredWordPairs: [WordPair] = [] @Published var searchText = "" { didSet { filterWordPairs() } } private var allWordPairs: [WordPair] = DataLoader.loadCSVFile() private var currentPage = 0 private let pageSize = 10 func wordPairsForPage(_ pageIndex: Int, pageSize: Int) -> ArraySlice<WordPair> { let startIndex = pageIndex * pageSize let endIndex = min(startIndex + pageSize, filteredWordPairs.count) if startIndex >= endIndex { return [] } return filteredWordPairs[startIndex..<endIndex] } var canGoToNextPage: Bool { return (currentPage + 1) * pageSize < filteredWordPairs.count } func gotoPreviousPage() { currentPage = max(currentPage - 1, 0) } func gotoNextPage() { if canGoToNextPage { currentPage += 1 } } private func filterWordPairs() { if searchText.isEmpty { filteredWordPairs = [] } else { let lowercaseSearchText = searchText.lowercased() filteredWordPairs = allWordPairs.filter { wordPair in let lowercasedWord1 = wordPair.Word1.lowercased() let lowercasedWord2 = wordPair.Word2.lowercased() return lowercasedWord1.contains(lowercaseSearchText) || lowercasedWord2.contains(lowercaseSearchText) || lowercasedWord1.range(of: lowercaseSearchText) != nil || lowercasedWord2.range(of: lowercaseSearchText) != nil } } currentPage = 0 // Reset currentPage when search text changes } }
问题原因及解决方案
问题根源
currentPage是私有变量且未添加@Published修饰,导致当filterWordPairs()中重置currentPage = 0时,SwiftUI视图无法感知到这个变化,仍然沿用旧的页码值进行渲染。
修改方案
- 为
currentPage添加@Published修饰,让视图能够监听其变化 - 保留
filterWordPairs()末尾的currentPage = 0逻辑,确保每次搜索文本变化(包括清空)都重置页码
修改后的代码
import SwiftUI class DictionaryViewModel: ObservableObject { @Published var filteredWordPairs: [WordPair] = [] @Published var searchText = "" { didSet { filterWordPairs() } } // 关键修改:添加@Published让视图监听页码变化,用private(set)限制外部修改权限 @Published private(set) var currentPage = 0 private let pageSize = 10 private var allWordPairs: [WordPair] = DataLoader.loadCSVFile() func wordPairsForCurrentPage() -> ArraySlice<WordPair> { let startIndex = currentPage * pageSize let endIndex = min(startIndex + pageSize, filteredWordPairs.count) if startIndex >= endIndex { return [] } return filteredWordPairs[startIndex..<endIndex] } var canGoToNextPage: Bool { return (currentPage + 1) * pageSize < filteredWordPairs.count } func gotoPreviousPage() { currentPage = max(currentPage - 1, 0) } func gotoNextPage() { if canGoToNextPage { currentPage += 1 } } private func filterWordPairs() { if searchText.isEmpty { filteredWordPairs = [] } else { let lowercaseSearchText = searchText.lowercased() filteredWordPairs = allWordPairs.filter { wordPair in let lowercasedWord1 = wordPair.Word1.lowercased() let lowercasedWord2 = wordPair.Word2.lowercased() // 移除重复判断:contains方法已包含range(of:)的逻辑 return lowercasedWord1.contains(lowercaseSearchText) || lowercasedWord2.contains(lowercaseSearchText) } } currentPage = 0 // 每次搜索文本变化都重置页码 } }
额外优化
- 移除了
filterWordPairs()中重复的range(of:)判断,简化代码逻辑 - 添加
private(set)修饰currentPage,确保外部只能通过指定方法修改页码,避免非法篡改
内容的提问来源于stack exchange,提问作者Htet
相关产品推荐
相关产品推荐

