如何在Swift房产APP中筛选MKCoordinateRegion范围内的房源数据
实现MKCoordinateRegion范围内房源过滤方案
实现逻辑
- 基于MKCoordinateRegion的经纬度范围规则,判断房源坐标是否落在当前展示的区域内
- 规则说明:MKCoordinateRegion的span属性代表区域整体的经纬度跨度,因此区域的经纬度上下限为中心坐标加减跨度的1/2
步骤1:添加区域包含判断工具方法
给MKCoordinateRegion加扩展,封装坐标是否在区域内的判断逻辑,方便复用:
import MapKit extension MKCoordinateRegion { /// 判断指定坐标是否在当前区域范围内 func contains(_ coordinate: CLLocationCoordinate2D) -> Bool { let minLat = center.latitude - span.latitudeDelta / 2 let maxLat = center.latitude + span.latitudeDelta / 2 let minLon = center.longitude - span.longitudeDelta / 2 let maxLon = center.longitude + span.longitudeDelta / 2 return coordinate.latitude >= minLat && coordinate.latitude <= maxLat && coordinate.longitude >= minLon && coordinate.longitude <= maxLon } }
步骤2:修改过滤方法新增区域过滤条件
确认你的Listing模型已经包含经纬度属性,示例假设Listing有latitude和longitude两个Double类型的属性存储经纬度,修改你的getListingsFiltered方法,在原有过滤条件中新增区域判断:
func getListingsFiltered(location: String, PriceMin: String, PriceMax: String, Bedrooms: Int ) { var listingsF = [Listing]() let lowestPrice = PriceMin == "Any" ? 0 : Int(PriceMin) ?? 0 let highestPrice = PriceMax == "Any" ? 1000000000 : Int(PriceMax) ?? 1000000000 for listing in self.results!.listings { // 价格过滤 guard let listingPrice = Int(listing.price), listingPrice >= lowestPrice, listingPrice <= highestPrice else { continue } // 卧室数量过滤 guard let listingBedrooms = Int(listing.bedrooms ?? ""), listingBedrooms >= Bedrooms else { continue } // 区域范围过滤 let listingCoordinate = CLLocationCoordinate2D( latitude: listing.latitude, longitude: listing.longitude ) guard self.region.contains(listingCoordinate) else { continue } // 所有条件匹配,加入结果数组 var l = Listing() l.name = listing.name l.neighborhood = listing.neighborhood l.url = listing.url l.price = listing.price l.city = listing.city l.state = listing.state l.zipcode = listing.zipcode // 其余属性赋值 listingsF.append(l) } DispatchQueue.main.async { self.listingsF = listingsF self.filters = true } }
注意事项
- 如果你需要支持用户未选择搜索位置时不过滤区域,可以在区域判断前加标记位判断,比如加个
hasSelectedLocation布尔值,为false时跳过区域过滤逻辑 - 如果你的
region属性声明为可选类型,将区域过滤的判断改为guard let region = self.region, region.contains(listingCoordinate) else { continue }即可处理空值情况 - 原代码中的强制解包建议替换为可选绑定,避免空值导致的崩溃
- 当用户拖动地图修改区域时,主动调用一次
getListingsFiltered即可刷新当前区域的房源列表
内容的提问来源于stack exchange,提问作者Nat Serrano
相关产品推荐
相关产品推荐

