LocationPicker
一个可以用于应用程序的现成且可完全定制的位置选择器。
功能
- 易于使用 - 在您的应用程序中集成完全功能的位置选择器只需要 5 行 代码。
LocationPicker
可在 Storyboard 中子类化或编程方式。 - 全面性 -
LocationPicker
提供了 闭包、代理和数据源、重写,以适应您的需求。 - 各种位置可供选择 - 用户可以从当前位置、搜索结果或应用程序提供的位置列表中选择位置。
- 完全可定制 -
LocationPicker
提供了大量可定制性,允许定制所有文本以及颜色和图标。如果您想进行深度定制,还可以访问原始 UI 元素如UISearchBar
、UITableView
、MKMapItem
。 - 无需担心权限 -
LocationPicker
会为您请求位置访问权限。
安装
Cocoapods
CocoaPods 是 Cocoa 项目的依赖管理器。
您可以使用以下命令安装它
$ gem install cocoapods
要使用 CocoaPods 将 LocationPicker
整合到您的 Xcode 项目中,请在您的 Podfile
中指定它
platform :ios, '8.0'
use_frameworks!
target 'YourApp' do
pod 'LocationPickerViewController'
end
Carthage
Carthage 是一个分散式的依赖管理器,它自动化了将框架添加到您的 Cocoa 应用程序的过程。
您可以使用以下命令通过 Homebrew 安装 Carthage
$ brew update
$ brew install carthage
要使用 Carthage 将 LocationPicker
整合到您的 Xcode 项目中,请在您的 Cartfile
中指定它
github "JeromeTan1997/LocationPicker"
Swift 包管理器
Swift 包管理器是管理 Swift 代码分发的工具。
Swift 包管理器目前仅在 Swift 3 开发快照中可用。
要使用 Swift 包管理器将 LocationPicker
整合到您的 Xcode 项目中,请在您的 Packages.swift
中指定它
import PackageDescription
let package = Package(
name: "Your Project Name",
targets: [],
dependencies: [
.Package(url: "https://github.com/JeromeTan1997/LocationPicker.git", versions: "2.0.0" ..< Version.max)
]
)
快速入门
程序化
导入 LocationPicker
import LocationPicker
注意:如果您通过 Cocoapods 安装
import LocationPickerViewController
通过导航控制器展示 LocationPicker
非常简单,只需创建一个,添加一个完成闭包并推进即可。
let locationPicker = LocationPicker()
locationPicker.pickCompletion = { (pickedLocationItem) in
// Do something with the location the user picked.
}
navigationController!.pushViewController(locationPicker, animated: true)
要展示 LocationPicker
,它需要嵌套在导航控制器中,以便可以关闭。
let locationPicker = LocationPicker()
locationPicker.pickCompletion = { (pickedLocationItem) in
// Do something with the location the user picked.
}
locationPicker.addBarButtons()
// Call this method to add a done and a cancel button to navigation bar.
let navigationController = UINavigationController(rootViewController: customLocationPicker)
presentViewController(navigationController, animated: true, completion: nil)
Storyboard
- 将 View Controller 拖拽到你的 Storyboard 中。
- 在 Identity inspector 中,在 Class 和 Module 字段中输入
LocationPicker
。注意:如果你是通过 Cocopods 安装的,那么 Module 字段应该是
LocationPickerViewController
- 创建一个 segue 并为其添加一个 Identifier。
- 在源视图控制器中添加以下代码。
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "Your Identifier" {
let locationPicker = segue.destinationViewController as! LocationPicker
locationPicker.pickCompletion = { (pickedLocationItem) in
// Do something with the location the user picked.
}
}
}
这就是在你的应用中拥有一个完全功能性的位置选择器的全部所需。多简单!
注意:要使用当前位置,别忘了在 info.plist
中添加 NSLocationWhenInUseUsageDescription
自定义
方法
func addBarButtons
此方法提供 3 个可选参数。可以设置 doneButtonItem
和 cancelButtonItem
为自定义的 UIBarButtonItem
对象。doneButtonOrientation
用于确定这两个按钮的对齐方式。如果没有提供任何参数,将使用两个系统样式的按钮,完成按钮将放在右侧。
调用此方法后,可以通过 barButtonItems
属性访问这两个按钮。
func setColors
此方法旨在更方便地设置颜色。themColor
将设置为currentLocationIconColor
、searchResultLocationIconColor
、alternativeLocationIconColor
、pinColor
。也可以通过此方法设置primaryTextColor
和secondaryTextColor
。
func setLocationDeniedAlertControllerTitle
此方法提供locationDeniedAlertController
的文本。
如果没有调用此方法,则警告控制器将显示如下:
授权按钮将直接用户引导到设置以更改位置访问权限。
布尔值
属性名称 | 默认值 | 目标 | 备注 |
---|---|---|---|
allowArbitraryLocation | false | 允许选择与搜索结果不匹配或完全匹配的位置 | |
mapViewZoomEnabled | true | mapView.zoomEnabled | 是否可以放大和缩小地图视图 |
mapViewShowsUserLocation | true | mapView.showsUserLocation | 是否在地图视图中显示用户的位置 |
mapViewScrollEnabled | true | mapView.scrollEnabled | 用户是否可以滚动地图视图 |
isRedirectToExactCoordinate | true | 查询后是否重定向到精确坐标 | |
alternativeLocationEditable | false | tableViewDataSource.tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) | 用户是否可以在表格视图中删除提供的位置 |
forceReverseGeocoding | false | 是否强制反向地理编码。如果将此属性设置为true ,则将进行反向地理编码 |
注意:如果alternativeLocationEditable
设置为true,请使用位置删除回调从数据库或内存中删除位置。
文本
属性名称 | 默认值 | 目标 | 备注 |
---|---|---|---|
currentLocationText | "Current Location" | currentLocationCell.locationNameLabel.text | 指示用户当前位置的文本 |
searchBarPlaceholder | "Search for location" | searchBar.placeholder | 指示用户进行位置搜索的文本 |
locationDeniedAlertTitle | "位置访问被拒绝" | alertController.title | 警报控制器标题的文本 |
locationDeniedAlertMessage | "授权位置访问以使用当前位置" | alertController.message | 警报控制器消息的文本 |
locationDeniedGrantText | "授权" | alertAction.title | 警报控制器“授权”按钮的文本 |
locationDeniedCancelText | "取消" | alertAction.title | 警报控制器“取消”按钮的文本 |
颜色
属性名称 | 默认值 | 目标 | 备注 |
---|---|---|---|
tableViewBackgroundColor | UIColor.whiteColor() | tableView.backgroundColor | 表格视图的背景颜色 |
currentLocationIconColor | UIColor(hue: 0.447, saturation: 0.731, brightness: 0.569, alpha: 1) | UIImage() | 当前位置单元格中显示的图标颜色,图标图像可通过属性currentLocationIconImage 更改 |
searchResultLocationIconColor | UIColor(hue: 0.447, saturation: 0.731, brightness: 0.569, alpha: 1) | UIImage() | 搜索结果位置单元格中显示的图标颜色,图标图像可通过属性searchResultLocationIconImage 更改 |
alternativeLocationIconColor | UIColor(hue: 0.447, saturation: 0.731, brightness: 0.569, alpha: 1) | UIImage() | 备用位置单元格中显示的图标颜色,图标图像可通过属性'alternativeLocationIconImage'更改 |
pinColor | UIColor(hue: 0.447, saturation: 0.731, brightness: 0.569, alpha: 1) | UIImage() | 地图视图中心显示的针的颜色,可通过属性pinImage 更改图标 |
primaryTextColor | UIColor(colorLiteralRed: 0.34902, green: 0.384314, blue: 0.427451, alpha: 1) | 多个 | 搜索栏和位置名称标签的文本颜色,在位置单元格中 |
secondaryTextColor | UIColor(colorLiteralRed: 0.541176, green: 0.568627, blue: 0.584314, alpha: 1) | 多个 | 位置地址标签在位置单元格中的文本颜色 |
图片
属性名称 | 目标 | 备注 |
---|---|---|
currentLocationIconImage | currentLocationCell.iconView.image | 当前位置单元格中显示的图标图像,此图像的颜色不会受属性currentLocationIconColor 的影响 |
searchResultLocationIconImage | searchResultLocationCell.iconView.image | 搜索结果位置单元格中显示的图标图像,此图像的颜色不会受属性searchResultLocationIconColor 的影响 |
alternativeLocationIconImage | alternativeLocationCell.iconView.image | 备用位置单元格中显示的图标图像,此图像的颜色不会受属性alternativeLocationIconColor 的影响 |
其他
属性名称 | 类型 | 默认值 | 备注 |
---|---|---|---|
alternativeLocations | [LocationItem]? | nil | 在当前位置和搜索结果位置下显示的位置 |
locationDeniedAlertController | UIAlertController? | nil | 当用户请求当前位置但拒绝应用的位置权限时出现的警报控制器 |
defaultLongitudinalDistance | Double | 1000 | 地图视图中展示的默认纵向距离,此时用户选择位置但尚未放大或缩小 |
searchDistance | Double | 10000 | 用于搜索位置的米距离 |
注意:
- 也可以通过数据源提供替代位置。
- 如果您对
LocationPicker
中包含的警告控制器感到满意,则无需设置locationDeniedAlertController
。您可以通过func setLocationDeniedAlertControllerTitle
更改默认警告控制器的文本。如果您想执行除了显示警告控制器之外的操作,可以采用权限拒绝处理程序回调。
回调函数
LocationPicker
提供了三种不同类型的回调函数,分别是闭包、代理和数据源以及覆盖,您可以选择您喜欢的任何一个。在大多数情况下,使用闭包是最方便的方法。如果您已经继承了LocationPicker
,则覆盖可能是最好的选择。
闭包
位置选择
此完成闭包用于获取用户的最终决定。它将在每次将要关闭每个LocationPicker
对象时执行一次。
locationPicker.pickCompletion = { (pickedLocationItem) in
// Do something with the location the user picked.
}
位置选择
此完成闭包用于获取用户每次位置选择。它会每当用户在列表中选择位置或在地图视图中拖动时执行。
locationPicker.selectCompletion = { (selectedLocationItem) in
// Do something with user's every selection.
}
位置删除
如果alternativeLocations
不为空并且alternativeLocationEditable
设置为true
,则用户在表格视图中删除位置项时将执行此闭包。
locationPicker.deleteCompletion = { (deletedLocationItem) in
// Delete the location.
}
权限拒绝处理器
默认情况下,当用户请求当前位置但未被应用程序的定位访问权限时,LocationPicker
将显示一个链接到“设置”的alert控制器。您可以通过调用func setLocationDeniedAlertControllerTitle
来更改alert控制器中的文本。如果您需要执行除了显示alert控制器之外的操作,您可以设置此闭包。
locationPicker.locationDeniedHandler = { (locationPicker) in
// Ask user to grant location access of this app.
}
委任和数据源
要使用委托或数据源,需要执行以下步骤:
- 遵循
LocationPickerDelegate
或LocationPickerDataSource
。
class YourViewController: LocationPickerDelegate, LocationPickerDataSource
- 将
delegate
或dataSource
设置为此类。
locationPicker.delegate = self
locationPicker.dataSource = self
- 实现
delegate
或dataSource
中的方法。
位置选择
此委托方法用于获取用户的最终决定。在将要关闭每个LocationPicker
对象时,只调用一次。
func locationDidPick(locationItem: LocationItem) {
// Do something with the location the user picked.
}
位置选择
此委托方法用于获取用户每次位置选择。每次用户在列表中选择位置或拖动地图视图时都会调用。
func locationDidSelect(locationItem: LocationItem) {
// Do something with user's every selection.
}
备用位置
此数据源方法用于提供显示在当前位置和搜索结果位置下的位置。除了使用委托外,您还可以仅设置alternativeLocations
属性。
func numberOfAlternativeLocations() -> Int {
// Get the number of locations you need to add to the location list.
return count
}
func alternativeLocationAtIndex(index: Int) -> LocationItem {
// Get the location item for the specific index.
return locationItem
}
位置删除
如果`alternativeLocations`不为空且`alternativeLocationEditable`设置为`true`,当用户在表格视图中删除一个位置项时,将调用此数据源方法。
func commitAlternativeLocationDeletion(locationItem: LocationItem) {
// Delete the location.
}
权限拒绝处理程序
默认情况下,当用户请求当前位置但拒绝应用程序的位置访问时,`LocationPicker`将显示指向设置的alert控制器。您可以通过调用`func setLocationDeniedAlertControllerTitle`来更改alert控制器中的文本。如果您需要进行除了显示alert控制器之外的操作,您可以将此代理方法设置。
func locationDidDeny(locationPicker: LocationPicker) {
// Ask user to grant location access of this app.
}
重载
如果您更喜欢继承`LocationPicker`,可以通过重载这些方法来实现与闭包和代理相同的结果。
位置选择
此方法用于获取用户的最终决定。当`LocationPicker`对象即将关闭时,对于每个`LocationPicker`对象只会调用一次。
override func locationDidPick(locationItem: LocationItem) {
// Do something with the location the user picked.
}
位置选择
此方法用于获取用户的每次位置选择。每次用户在列表中选择位置或拖动地图视图时,都会调用。
注意:如果您重载了这些方法,相应的闭包和代理方法将不会执行。
override func locationDidSelect(locationItem: LocationItem) {
// Do something with user's every selection.
}
位置删除
如果alternativeLocations
不为空且alternativeLocationEditable
设置为true
,当用户在表视图中删除位置项目时,将调用此方法。
override func alternativeLocationDidDelete(locationItem: LocationItem) {
// Delete the location.
}
权限拒绝处理器
默认情况下,当用户请求当前位置但拒绝应用程序访问位置权限时,LocationPicker
将显示一个连接到设置的警报控制器。您可以通过调用func setLocationDeniedAlertControllerTitle
来更改警报控制器中的文本。如果您需要执行其他操作而不是显示警报控制器,您可以设置此方法。
override func locationDidDeny(locationPicker: LocationPicker) {
// Ask user to grant location access of this app.
}
位置项目
LocationItem
是MKMapItem
的封装类,可让您无需在项目中每个位置导入MapKit
。为了使其更便于使用,它提供了几个计算属性来访问MKMapItem
。
存储
LocationItem
符合NSCoding
,这意味着可以将LocationItem
对象编码为NSData
对象,然后将其解码回来。
let locationData = NSKeyedArchiver.archivedDataWithRootObject(locationItem)
let locationItem = NSKeyedUnarchiver.unarchiveObjectWithData(locationData) as! LocationItem
可比较的
LocationItem
的哈希值为"\(coordinate.latitude), \(coordinate.longitude)".hashValue
,因此具有相同纬度和经度的对象是相等的。
属性
属性名称 | 类型 | 目标 | 备注 |
---|---|---|---|
名称 | String | mapItem.name | 位置的名称 |
坐标 | (纬度: Double, 经度: Double)? | mapItem.placemark.coordinate | 位置的坐标和转换为元组。如果用户离线或没有搜索结果且将 LocationPicker 的 allowArbitraryLocation 属性设置为 true ,则此属性将为 nil |
addressDictionary | [NSObject: AnyObject]? | mapItem.placemark.addressDictionary | 位置的地址字典 |
formattedAddressString | String? | addressDictionary?["FormattedAddressLines"] | 根据用户的区域格式化地址文本 |
如果您想访问 MKMapItem
对象的其他属性,只需调用 locationItem.mapItem
即可。
初始化
init(mapItem: MKMapItem)
由于 LocationItem
只是 MKMapItem
的封装,当然您可以创建一个包含 MKMapItem
对象的 LocationItem
。
init(coordinate: (纬度: Double, 经度: Double), addressDictionary: [String: AnyObject])
您也可以用坐标和地址字典进行初始化。
如果您不想将 LocationItem
对象存储为 NSData
,您只需存储坐标和地址字典,并使用此方法进行初始化。
init(locationName: String)
可以使用仅名称创建位置。在这种情况下,属性coordinate的值将会是nil。
更改日志
贡献
- 如果您遇到任何错误或其他问题,请创建问题或 pull 请求。
- 如果您想为
LocationPicker
添加更多功能,我们非常欢迎您创建 pull 请求。 - 如果您擅长英语,请纠正我的英语。
- 如果您喜欢这个项目,请将其星标并分享给其他人。
- 如果您已经在您的应用程序中使用LocationPicker,请通过创建问题来告诉我。
许可
MIT许可(MIT)
版权所有 (c) 2016 Jerome Tan
以下条件下免费允许任何人获得本软件及其相关的文档文件(以下称为“软件”)的副本,不受限制地处理软件,包括但不限于使用、复制、修改、合并、出版、分发、再许可和/或出售软件的副本,并允许取得软件的人员处理软件,前提是:
上述版权声明和本许可声明应包含在软件的所有副本或主要部分的副本中。
本软件按“现状”提供,不提供任何明示或暗示的保证,包括但不限于适销性、特定目的适用性和非侵权性保证。在任何情况下,作者的版权所有者不应对由软件或其使用或其他操作而产生的任何索赔、损害或其他责任承担责任,无论这些责任是基于合同、侵权或其他原因。