Как реализовать слой "отслеживания пальцев" в приложении, таком как iOS Simulator

Теперь, когда наше приложение доставлено, у нашего ответственного за обучение есть запрос:

"Приложение классное, но нам нужен режим, показывающий движение пальцев, например, как жесты отображаются в режиме лазерной указки на симуляторе или iPad в Keynote [чтобы мы могли снимать фильмы]".

Это приложение, которое использует UITabBarController с XIB для каждой вкладки (4). Это довольно сложное приложение с интерактивными распознавателями жестов, и мне снились кошмары "во-первых, не навреди"...

Я попытался добавить простой "глобальный UIView" над контроллером вкладок, используя схему здесь: http://www.james-vandyne.com/creating-universal-overlays-using-uiviews-on-ios/

Моя попытка "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 для создания / определения местоположения и не встраиваю их в код с нуля, поэтому вполне возможно, что есть (a?/ Несколько?) Простые свойства UIView, которые я не настраиваю правильно... но я не могу видеть это. Или я попаду в неприятности с этим, пытаясь продвигать события по цепочке?

1 ответ

Решение

Есть хорошая основа под названием FingerTips, которая делает это.

Его также легко реализовать, и он показывает круги только при наличии внешнего дисплея, поэтому вы представляете его.

Другие вопросы по тегам