1

现在我们的应用已经发货了,我们的培训负责人有一个要求:

“该应用程序很酷,但我们需要一种显示手指运动的模式,例如手势在模拟器中的显示方式或 iPad 在 Keynote 中的激光笔模式[这样我们就可以拍摄电影]。”

这是一个使用 UITabBarController 和每个选项卡 (4) 的 xibs 的应用程序。这是一个带有交互手势识别器的非常复杂的应用程序,我正在做“首先,不要伤害”的噩梦......

我尝试使用此处的方案在选项卡控制器上方添加一个简单的“全局 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- 不要开火。(是的,我已经开启UserInteractionEnabledsetMultipleTouchEnabled这个全局视图)。幸运的是,我没有在下面的任何事情上搞砸手势识别 - 其他视图正在获取事件,并且应用程序在此全局视图下正常运行。

通常我使用 IB 来构建/定位视图,而不是从头开始在代码中构建它们,所以很可能有(一个?/几个?)简单的 UIView 属性我没有设置正确......但我不能看见。还是我会让自己陷入困境,试图将事件沿着链条转发?

4

1 回答 1

1

有一个很好的框架叫做 FingerTips 可以做到这一点。

它也很容易实现,如果有外部显示器,它只会显示圆圈,以便您展示它。

于 2012-09-25T17:48:56.743 回答