MKMapview有提供自己的- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated 事件監測地圖移動
唯一缺點是不能檢查是使用者拖動還是程式移動
對我而言,導致的主要問題是第一次進入時就會觸發事件
因為我打算在移動地圖時讓某些元件半透明增加可視區域
這問題會引起一些小小的 UX 遺憾
所以採用了額外的監測方式:
使用 UIGesture 檢查是否為使用者移動,是的話才呼叫程式
一、設定 UIGesture
//加入手勢偵測
UIPanGestureRecognizer *mapPan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(hideMapItems:)]; //使用者移動時隱藏物件
mapPan.delegate=self;
[mapPan setMinimumNumberOfTouches:1];
[mapPan setMaximumNumberOfTouches:1];
[self.h_map addGestureRecognizer:mapPan];
isMapPanned = NO; //flag
isMapPanned 這邊作為flag, 使用者第一次觸發後就成立,因為這時地圖已經載入完成,不需擔心regionDidChangeAnimated 事件被重複觸發(ios 5.1.1下,ios6 應該也不用擔心?)
另外要注意的是,mapview 不能直接套 UIGesture
因為 MKMapView 有自己的手勢偵測 http://stackoverflow.com/questions/5005597/uipangesturerecognizer-on-mkmapview
所以必須要指定委託並實作方法
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
isMapPanned = YES;
return YES;
}
二、設定相關方法
//檢測使用者畫面移動
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
//使用者開始移動結束,重新顯示物件
if (isMapPanned) {
[self showMapItems:nil];
}
}
此方法不算完美,在網路連線不佳時,有可能發生地圖資料尚未載入完成,使用者就先移動的情況
不過因為相關物件已經載入完成,所以實作上目前沒有看到問題