2015-03-25 72 views
0

我試圖用覆蓋視圖實現一個MKMapView,該視圖繪製了一個可編輯的多邊形。因此,我需要選擇性地捕捉針對頂點的觸摸手勢,但通過其他觸摸/手勢來允許滾動和縮放地圖。帶有覆蓋視圖的iOS MKMapView捕捉選定的觸摸/手勢

那麼,如何以編程方式將選定的觸摸發送到地圖或疊加層,具體取決於它們的座標?

以下代碼將其歸結爲一個簡化的方案:覆蓋視圖的左側爲紅色,右側爲藍色。一方應該抓住觸摸事件,另一方應該允許地圖交互。

兩個,地圖和疊加,都在子視圖一個SuperView

public sealed class SuperView: UIView 
{ 
    readonly UIView map = new MapView(); 
    readonly UIView overlay = new Overlay(); 

    public SuperView() 
    { 
     AddSubview(map); 
     AddSubview(overlay); 
    } 

    public override UIView HitTest(CGPoint point, UIEvent uievent) 
    { 
     return point.X < Frame.Width/2 ? map : overlay; 
    } 
} 

MapViewMKMapView派生,纔有一定要允許滾動:

public sealed class MapView: MKMapView 
{ 
    public MapView() : base(UIScreen.MainScreen.Bounds) 
    { 
     ScrollEnabled = true; 
    } 
} 

Overlay包括手勢識別和可視化兩個區域:

public sealed class Overlay: UIView 
{ 
    public Overlay() : base(UIScreen.MainScreen.Bounds) 
    { 
     BackgroundColor = new UIColor(0, 0, 0, 0); 
     AddGestureRecognizer(new Recognizer()); 
    } 

    public override void Draw(CGRect rect) 
    { 
     using (var context = UIGraphics.GetCurrentContext()) { 
      context.SetFillColor(new CGColor(1, 0, 0, 0.25f)); 
      context.FillRect(new CGRect(rect.Left, rect.Top, rect.Width/2, rect.Height)); 
      context.SetFillColor(new CGColor(0, 0, 1, 0.25f)); 
      context.FillRect(new CGRect(rect.Width/2, rect.Top, rect.Width/2, rect.Height)); 
     } 
    } 
} 

識別器是直截了當:

public sealed class Recognizer: UIGestureRecognizer 
{ 
    public override void TouchesBegan(NSSet touches, UIEvent evt) 
    { 
     Console.WriteLine("TouchesBegan"); 
     base.TouchesBegan(touches, evt); 
    } 

    public override void TouchesMoved(NSSet touches, UIEvent evt) 
    { 
     Console.WriteLine("TouchesMoved"); 
     base.TouchesMoved(touches, evt); 
    } 

    public override void TouchesEnded(NSSet touches, UIEvent evt) 
    { 
     Console.WriteLine("TouchesEnded"); 
     base.TouchesEnded(touches, evt); 
    } 

    public override void TouchesCancelled(NSSet touches, UIEvent evt) 
    { 
     Console.WriteLine("TouchesCancelled"); 
     base.TouchesCancelled(touches, evt); 
    } 
} 

結果屏幕看起來如下:

enter image description here

當觸及紅色的部分,我希望與地圖進行互動 - 這沒有按」工作。 當觸摸藍色部分時,我想看到手勢識別器的控制檯輸出 - 確實可行。

什麼不起作用:

  • 重新調整的疊加只有屏幕的一半。

    在這個人造的例子中,這將有所幫助。但在我的真實應用中,觸摸和非觸摸之間的區別更爲複雜。

  • 將手勢檢測器添加到MapView

    由於each gesture recognizer will receive touch events in a non-deterministic order,您永遠不知道地圖或手勢檢測器是否首先收到觸摸事件。所以即使觸摸不應該收到地圖,地圖也可能已經滾動。

  • 覆蓋HitTestPointInside

    我試圖覆蓋這些方法在SuperView,MapView和/或Overlay。但是他們要麼沒有被調用,要麼似乎沒有效果。至少我可以阻止手勢識別器在紅色區域接收觸摸。但它沒有按預期到達地圖。也許我做錯了什麼。但看起來地圖忽略了轉發。

回答

0

我似乎已經解決了上述問題。顯然,MKMapView不應該是一個子視圖,但需要的是ViewViewController的:

public sealed class SuperView: UIViewController 
{ 
    readonly UIView map = new MKMapView(); 
    readonly UIView overlay = new Overlay(); 

    public SuperView() 
    { 
     View = map; 
     map.AddSubview(overlay); 
    } 
} 

然後Overlay觀點得到HitTest實現:

public override UIView HitTest(CGPoint point, UIEvent uievent) 
    { 
     return point.X < Frame.Width/2 ? null : base.HitTest(point, uievent); 
    }