Core Motion
使用CMMotionManager。首先检查你想用的硬件是否可用,接下来说明你要获取数据的频率,最后注册一个闭包,每次得到新值时执行。
在这里可调用的硬件传感器有:加速度传感器,陀螺仪,磁感应器。他们都通过CMMotionManager来访问。由于整个设备只有一个这些设备,所以这样的访问放在一个全局的地方比放在某一个Class里妥当,AppDelegate成为了最合适的地方。在使用前先引包。
import UIKit import CoreMotion @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? struct Motion { static let manager = CMMotionManager() } }获取到了这个Manager以后,就可以在其他类里使用了:
let motionManager = AppDelegate.Motion.manager if motionManager.accelerometerAvailable {//检查加速度传感器是否可用 //在新值传回来之后会在指定的队列执行下面的闭包 motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue.mainQueue()) { (data, error) -> Void in self.bouncer.gravity.gravityDirection = CGVector(dx: data.acceleration.x, dy: -data.acceleration.y) } }如果你开始了获取数据,那么一定要记得结束获取,通常在viewWillDisappear方法里:
AppDelegate.Motion.manager.stopAccelerometerUpdates()Core Location
这是一个管理位置和朝向的底层框架,不涉及UI部分。有几个预置好的精度等级,会用到不同的定位方法,GPS,WiFi,基站。精度越高越耗电。
你需要得到用户的授权来获取定位信息,这需要你在Info.plist里加入一行key。
定位的模式有这么几个:高精度实时定位,当我的位置发生显著变化时的定位,当进入一个区域时,朝向发生变化时。这些定位会发生在你的应用程序不在运行的时候。
Map Kit
使用的是MKMapView,在这上面可以显示MKAnnotation的标注点,就是那个大头针。
在StoryBoard里选择MapView,拖到代码里初始化:
@IBOutlet weak var mapView: MKMapView! { didSet { mapView.mapType = .Satellite//设置地图模式 mapView.delegate = self//设置自己为代理来实现各种方法 } }
找一个合适的类来实现MKAnnotation协议:
import MapKit class myGPS: NSObject, MKAnnotation{ var coordinate: CLLocationCoordinate2D var title: String! var subtitle: String! init(coorX: Double, coorY: Double, initTitle: String, initSubtitle: String){ coordinate = CLLocationCoordinate2D(latitude: coorX, longitude: coorY) title = initTitle subtitle = initSubtitle } }现在初始化过的myGPS就可以作为地图上的一个点来显示了,直接在mapView下添加单个或数组:
mapView.addAnnotations(myGPSs)
func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! { //先看看是否有可以复用的View var view = mapView.dequeueReusableAnnotationViewWithIdentifier("wayPoint") if view == nil { //如果没有则新建一个,注意ID是要一样的 view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "wayPoint") view.canShowCallout = true } else { //如果有可以复用的,则直接使用 view.annotation = annotation } //定制左右View view.leftCalloutAccessoryView = nil view.rightCalloutAccessoryView = nil if let gps = annotation as? myGPS { view.leftCalloutAccessoryView = UIImageView(frame: CGRect(origin: CGPointZero, size: CGSize(width: 59, height: 59))) view.rightCalloutAccessoryView = UIButton.buttonWithType(UIButtonType.DetailDisclosure) as! UIButton } return view }如果你的弹出框里有图片之类的大东西,不需要在上面设置View时直接加载好,在点击每一个大头针时加载就好了:
//左View是一个图片,不需要在annotation设置时就载入图片,在某一个被选中时加载即可 func mapView(mapView: MKMapView!, didSelectAnnotationView view: MKAnnotationView!) { if let gps = view.annotation as? myGPS { if let imageView = view.leftCalloutAccessoryView as? UIImageView { imageView.image = UIImage(named: "1") } } }
//这里是弹出框点击事件,执行了一个Segue func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, calloutAccessoryControlTapped control: UIControl!) { performSegueWithIdentifier("showBigImage", sender: view) }
可以使用MKLocalSearch来搜索地点,这是需要网络的,他会返回给你一个MKMapItem,这是一个包含很多信息的东西,地图可以读取并显示它。
MKDirections,和搜索地点的API类似,返回起点和终点的MapItem和MKRoutes。MKRoutes包括这条路线的详细信息和ETA,还有用于在地图上画出这条路线的MKPolyline。
Overlays可以在地图上绘制路线等,使用MKOverlayRender来渲染,一般使用系统自带的渲染,也可以自己写。