1

さまざまな形の建物を含む 3D マップがあります。ユーザーにマップ上の建物をクリックしてもらいたいと思います。これは、新しいビューへのセグエとして機能します。

建物と同じ形の目に見えないボタンを作成し、それらをイメージビュー (マップを保持する) の上に配置することで、これを実現することを計画しました。

いくつか読んだ後、カスタムボタンを作成するのは思ったほど簡単ではないことがわかりました(50以上の異なる形状のボタンがある場合、多くのサブキャッシングとカスタマイズを行う必要があると思います.この問題を解決するために使用できる別のアプローチがあるかどうか疑問に思っていました。


編集:すべての機能が機能していることを今すぐ追加する必要がありますが、アルファが0.1に設定されたデフォルトの長方形のボタンを使用する必要があります。

4

2 に答える 2

3

データモデルを改善するために編集

これを行うには、マップ イメージを背景に持つ UIView を用意します。これは、UIImageView を使用するか、drawRect で自分で画像をレンダリングすることによって行うことができます。

次に、いくつかの CGPath 参照を定義します。このようなことを行うことで、建物ごとに 1 つ...ポイントの配列から CGPathRef を作成する方法ポイントは、各建物の角になります。

これらのパスを何らかの方法で配列に格納します。「クリック可能な」建物ごとに 1 つのパスが必要です。

建物オブジェクトか何かの中にパスを保存します...

@interface Building : NSObject

@property (nonatomic) CGPath path;

@end

UIView サブクラスでオーバーライドします- (void)touchesBegan...。次に、タッチポイントを取得し、パスを反復処理して、タッチされたパスを見つけることができます...

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];

    CGPoint touchPoint = [touch locationInView:self];

    for (Building *building in self.buildings) {
        if (CGPathContainsPoint(building.path, CGAffineTransformIdentity, touchPoint, YES)) {
            //the touch was inside this building!
            //now do something with this knowledge.
        }
    }
}
于 2013-02-12T14:12:25.930 に答える
1

一度、meteo アプリケーションを実装する必要がありました。マップを作成しました - いくつかのクリック可能な領域があります。これらの非長方形領域を定義する最も簡単な方法は、それらを として定義しUIBezierPath、UIBezierPath を使用してUITapGestureRecognizer CGPath を使用することですが、これは純粋な Objective-C です。CGPath のその他の利点として、ランダムな色を使用してこれらのパスを簡単に塗りつぶしたりストロークしたりできます。これは、デバッグ時にパスを確認するのに便利です。

そう

//in you .h, or in class extension

//an array of UIBezierPath you create
// each bezierPath represent an area.
@property (nonatomic, strong) NSArray *myShapes;

//in your .m

- (void)viewDidLoad
{
    [super viewDidLoad];
    //load stuff
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
    [self.view addGesture:tap];

    // ...
}

- (void)handleTap:(UITapGestureRecognizer *)tap
{
    UIBezierPath *recognizedArea = nil;
    //if your shapes are defined in self.view coordinates : 
    CGPoint hitPoint = [tap locationInView:self.view];
    for(UIBezierPath *regionPath in self.myShapes){
        if([regionPath containsPoint:tap]){
            recognizedArea = regionPath;
            break;
        }
    }
    //handle touch for THIS specific area when recognizedArea isn't nil
    if(recognizedArea){
        //YOUR CODE HERE
    }
    // you might also iterate with a normal integer increment
    // and use the path index to retrieve region-specific-data from another array

}
于 2013-02-12T15:03:41.260 に答える