1

アプリが出荷されたので、トレーニング担当者から次のリクエストがあります。

「アプリはかっこいいですが、シミュレーターでジェスチャーがどのように表示されるか、KeynoteでiPadのレーザーポインターモードなど、指の動きを表示するモードが必要です[フィルムをキャプチャできるようにするため]。」

これは、タブごとにxibsを備えたUITabBarControllerを使用するアプリです(4)。これは、ジェスチャーレコグナイザーが相互作用する非常に複雑なアプリであり、私は「最初に、害を及ぼさない」という悪夢を抱えていました...

http://www.james-vandyne.com/creating-universal-overlays-using-uiviews-on-ios/のスキームを使用して、タブコントローラーの上に単純な「グローバルUIView」を追加してみました。

私の「PresentationView」の試み:

私のアプリデリゲート:

UIWindow *mainWindow = [[UIApplication sharedApplication] keyWindow];
[self setPresentationView:[[PresentationView alloc] initWithFrame: [mainWindow frame]]];
[mainWindow insertSubview:presentationView aboveSubview:mainWindow];

クラス:

//  PresentationView.h
#import <UIKit/UIKit.h>

@interface PresentationView : UIView
{
    NSMutableDictionary *touchesInView;
}
@property (nonatomic, retain) NSMutableDictionary *touchesInView;
@end


#import "PresentationView.h"
#import "TouchPoint.h"

@implementation PresentationView
@synthesize touchesInView;

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        [ self setAlpha:0.1];
        [self setBackgroundColor:[UIColor whiteColor]];

        [self setUserInteractionEnabled:YES];
        [self setMultipleTouchEnabled:YES];
        touchesInView = [[NSMutableDictionary alloc] init];
    }
    return self;
}

- (void) dealloc
{
    [touchesInView release];
    touchesInView = nil;

    [super dealloc];
}

- (void)drawRect:(CGRect)rect
{
    if ([touchesInView count] < 1)
        return;

    CGContextRef context = UIGraphicsGetCurrentContext();
    NSEnumerator *touchEnum = [touchesInView objectEnumerator];
    TouchPoint *nextTouch;
    float rad = 24;

    while (nextTouch = [touchEnum nextObject]) {
        [[ UIColor redColor] set];
        CGContextAddArc(context, nextTouch.current.x, nextTouch.current.y, rad, 0.0, M_PI*2, 1);
        CGContextFillPath(context);
        CGContextStrokePath(context);
    }
}

- (UIView *) hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    [self setNeedsDisplay];

    return [[[[[UIApplication sharedApplication] keyWindow] subviews] objectAtIndex:0] hitTest:point withEvent:event];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    for( UITouch *t in touches )
    {
        NSValue *key = [NSValue valueWithPointer:t];
        CGPoint loc = [t locationInView:self];
        TouchPoint *newTouch = [[TouchPoint alloc] init];

        [newTouch setBegan:loc];
        [newTouch setCurrent:loc];
        [newTouch setTapCount:[t tapCount]];

        [touchesInView setObject:newTouch forKey:key];

        [newTouch release];
    }
    [self setNeedsDisplay];

    [[[[[UIApplication sharedApplication] keyWindow] subviews] objectAtIndex:0] touchesBegan:touches withEvent:event];
}
// More touch methods- all ignored

これはちょっとうまくいきます-ビューは他のすべてのビューの上にあり、hitTest:withEvent:発火し、のヒットポイントで赤い円を描くことに成功しましたdrawRect:

しかし、タッチを追跡しようとすると故障します-発射touchesBegan/Moved/Endedしないでください。(はい、私はこのグローバルビューをオンにしUserInteractionEnabledました)。setMultipleTouchEnabled幸い、以下のジェスチャ認識を台無しにしていません。他のビューはイベントを取得しており、アプリはこのグローバルビューの下で正常に動作しています。

通常、私はIBを使用してビューを構築/配置し、コードで最初から構築しないので、正しく設定していない(?/いくつかの?)単純なUIViewプロパティがある可能性が非常に高いです...しかし、私はできません見てください。それとも、イベントをチェーンの下流に転送しようとして、これに問題を抱えることになりますか?

4

1 に答える 1

1

これを行うには、FingerTips という優れたフレームワークがあります。

実装も簡単で、外部ディスプレイがある場合にのみ円を表示するので、それを提示しています。

于 2012-09-25T17:48:56.743 に答える