有没有办法确定是否拖动了MKMapView?
我想在每次用户拖动地图时获取中心位置,CLLocationCoordinate2D centre = [locationMap centerCoordinate];但是我需要一个委托方法或者一旦用户使用地图导航就会触发.
提前致谢
Jan*_*ano 232
当区域因任何原因发生变化时,接受的答案中的代码将触发.要正确检测地图拖动,您必须添加UIPanGestureRecognizer.顺便说一句,这是拖动手势识别器(平移=拖动).
第1步:在viewDidLoad中添加手势识别器:
-(void) viewDidLoad {
[super viewDidLoad];
UIPanGestureRecognizer* panRec = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(didDragMap:)];
[panRec setDelegate:self];
[self.mapView addGestureRecognizer:panRec];
}
Run Code Online (Sandbox Code Playgroud)
步骤2:将协议UIGestureRecognizerDelegate添加到视图控制器,使其作为委托.
@interface MapVC : UIViewController <UIGestureRecognizerDelegate, ...>
Run Code Online (Sandbox Code Playgroud)
第3步:并添加以下代码为UIPanGestureRecognizer与在的MKMapView已有的手势识别工作:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
Run Code Online (Sandbox Code Playgroud)
第4步:如果您想要一次调用您的方法一次而不是每次拖动50次,请检测选择器中的"拖动结束"状态:
- (void)didDragMap:(UIGestureRecognizer*)gestureRecognizer {
if (gestureRecognizer.state == UIGestureRecognizerStateEnded){
NSLog(@"drag ended");
}
}
Run Code Online (Sandbox Code Playgroud)
Sno*_*man 70
这是检测平移以及用户启动的缩放更改的唯一方法:
- (BOOL)mapViewRegionDidChangeFromUserInteraction
{
UIView *view = self.mapView.subviews.firstObject;
// Look through gesture recognizers to determine whether this region change is from user interaction
for(UIGestureRecognizer *recognizer in view.gestureRecognizers) {
if(recognizer.state == UIGestureRecognizerStateBegan || recognizer.state == UIGestureRecognizerStateEnded) {
return YES;
}
}
return NO;
}
static BOOL mapChangedFromUserInteraction = NO;
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
mapChangedFromUserInteraction = [self mapViewRegionDidChangeFromUserInteraction];
if (mapChangedFromUserInteraction) {
// user changed map region
}
}
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
if (mapChangedFromUserInteraction) {
// user changed map region
}
}
Run Code Online (Sandbox Code Playgroud)
小智 27
查看MKMapViewDelegate参考.
具体来说,这些方法可能有用:
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
Run Code Online (Sandbox Code Playgroud)
确保设置了地图视图的委托属性,以便调用这些方法.
hEA*_*ASH 26
(只是)Swift版@mobi的优秀解决方案:
private var mapChangedFromUserInteraction = false
private func mapViewRegionDidChangeFromUserInteraction() -> Bool {
let view = self.mapView.subviews[0]
// Look through gesture recognizers to determine whether this region change is from user interaction
if let gestureRecognizers = view.gestureRecognizers {
for recognizer in gestureRecognizers {
if( recognizer.state == UIGestureRecognizerState.Began || recognizer.state == UIGestureRecognizerState.Ended ) {
return true
}
}
}
return false
}
func mapView(mapView: MKMapView, regionWillChangeAnimated animated: Bool) {
mapChangedFromUserInteraction = mapViewRegionDidChangeFromUserInteraction()
if (mapChangedFromUserInteraction) {
// user changed map region
}
}
func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
if (mapChangedFromUserInteraction) {
// user changed map region
}
}
Run Code Online (Sandbox Code Playgroud)
dst*_*t3p 13
Swift 3解决方案对Jano的答案如下:
将Protocol UIGestureRecognizerDelegate添加到ViewController
class MyViewController: UIViewController, UIGestureRecognizerDelegate
Run Code Online (Sandbox Code Playgroud)
创建UIPanGestureRecognizer viewDidLoad并设置delegate为self
viewDidLoad() {
// add pan gesture to detect when the map moves
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(self.didDragMap(_:)))
// make your class the delegate of the pan gesture
panGesture.delegate = self
// add the gesture to the mapView
mapView.addGestureRecognizer(panGesture)
}
Run Code Online (Sandbox Code Playgroud)
添加协议方法,以便您的手势识别器可以使用现有的MKMapView手势
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
Run Code Online (Sandbox Code Playgroud)
添加将在平移手势中由选择器调用的方法
func didDragMap(_ sender: UIGestureRecognizer) {
if sender.state == .ended {
// do something here
}
}
Run Code Online (Sandbox Code Playgroud)
另一种可能的解决方案是在保存地图视图的视图控制器中实现touchesMoved :(或touchesEnded:等),如下所示:
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
for (UITouch * touch in touches) {
CGPoint loc = [touch locationInView:self.mapView];
if ([self.mapView pointInside:loc withEvent:event]) {
#do whatever you need to do
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
在某些情况下,这可能比使用手势识别器更简单.
根据我的经验,类似于"打字时搜索",我发现计时器是最可靠的解决方案.它不需要添加额外的手势识别器来进行平移,捏合,旋转,敲击,双击等.
解决方案很简单:
当计时器触发时,加载新区域的标记
import MapKit
class MyViewController: MKMapViewDelegate {
@IBOutlet var mapView: MKMapView!
var mapRegionTimer: NSTimer?
// MARK: MapView delegate
func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
setMapRegionTimer()
}
func setMapRegionTimer() {
mapRegionTimer?.invalidate()
// Configure delay as bet fits your application
mapRegionTimer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "mapRegionTimerFired:", userInfo: nil, repeats: false)
}
func mapRegionTimerFired(sender: AnyObject) {
// Load markers for current region:
// mapView.centerCoordinate or mapView.region
}
}
Run Code Online (Sandbox Code Playgroud)您还可以在Interface Builder中向地图添加手势识别器.将它链接到你的viewController中的动作插座,我称之为"mapDrag"......
然后你会在viewController的.m中做这样的事情:
- (IBAction)mapDrag:(UIPanGestureRecognizer *)sender {
if(sender.state == UIGestureRecognizerStateBegan){
NSLog(@"drag started");
}
}
Run Code Online (Sandbox Code Playgroud)
确保你也有这个:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
Run Code Online (Sandbox Code Playgroud)
当然,你必须在你的.h文件中使你的viewController成为UIGestureRecognizerDelegate才能使它工作.
否则,地图的响应者是唯一听到手势事件的人.
这些解决方案中有很多都存在问题,而不是Swift想要的,所以我选择了一个更干净的解决方案。
我只是将MKMapView子类化,并覆盖touchesMoved。尽管此代码段不包含该代码段,但我建议创建一个委托或通知以传递您想要的有关该运动的任何信息。
import MapKit
class MapView: MKMapView {
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesMoved(touches, with: event)
print("Something moved")
}
}
Run Code Online (Sandbox Code Playgroud)
您将需要更新情节提要文件上的类以指向此子类,以及修改通过其他方式创建的任何地图。
要识别地图视图上的任何手势何时结束:
这对于仅在用户完成缩放/旋转/拖动地图后才执行数据库查询非常有用。
对我来说, regionDidChangeAnimated 方法仅在手势完成后才被调用,并且在拖动/缩放/旋转时不会被多次调用,但知道它是否是由手势引起的很有用。
我知道这是一篇旧文章,但这里是我的Jano 答案的 Swift 4/5 代码,带有平移和捏合手势。
class MapViewController: UIViewController, MapViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(self.didDragMap(_:)))
let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(self.didPinchMap(_:)))
panGesture.delegate = self
pinchGesture.delegate = self
mapView.addGestureRecognizer(panGesture)
mapView.addGestureRecognizer(pinchGesture)
}
}
extension MapViewController: UIGestureRecognizerDelegate {
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
@objc func didDragMap(_ sender: UIGestureRecognizer) {
if sender.state == .ended {
//code here
}
}
@objc func didPinchMap(_ sender: UIGestureRecognizer) {
if sender.state == .ended {
//code here
}
}
}
Run Code Online (Sandbox Code Playgroud)
享受!
| 归档时间: |
|
| 查看次数: |
46305 次 |
| 最近记录: |