2012年10月26日 星期五

MKMapView 使用者拖移事件檢查

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];

}

}

此方法不算完美,在網路連線不佳時,有可能發生地圖資料尚未載入完成,使用者就先移動的情況

不過因為相關物件已經載入完成,所以實作上目前沒有看到問題

沒有留言: