Как реализовать слой "отслеживания пальцев" в приложении, таком как 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, которая делает это.
Его также легко реализовать, и он показывает круги только при наличии внешнего дисплея, поэтому вы представляете его.