UIPinchGestureRecognizer选择器未在UIImageView上调用

时间:2012-12-03 09:07:53

标签: ios uiimageview uigesturerecognizer uipinchgesturerecognizer

我一直在努力解决这个问题几个小时,完全不知所措。我正在尝试为我的游戏中的一些自定义UIImageViews实现UIPinchGestureRecognizer,但它不起作用。我研究过的所有东西都说应该有用,但事实并非如此。如果我将它添加到我的视图控制器或自定义UIView,而不是UIImageViews,Pinch工作正常。我已经尝试了所有常见的修复和调整,但没有成功。我将userInteractionEnabledmultipleTouchEnabled设置为YES。我已正确设置委托和选择器。我shouldRecognizeSimultaneouslyWithGestureRecognizer设置为返回YES。

手势识别器正在添加到UIImageView中,我以后能够在更新循环中访问其属性,但是当我尝试捏时,选择器中的NSLog永远不会被调用UIImageView。我已经调整了视图的z位置,以确保它们位于顶部,但没有骰子。

我的UIImageViews存储在NSMutableDictionary中,并通过在游戏的每个更新循环中循环来更新。这会对UIPinchGestureRecognizer没有被调用产生影响吗?...我想不出任何其他内容并且发布代码可能无济于事 - 因为当它用于UIView或视图控制器时,相同的确切代码可以正常工作。 / p>

我在视图控制器的touchesBegan和touchMoved事件中确实有触摸处理代码......但是我已经将其关闭但问题仍然存在,并且无论如何,其他元素的捏合也是如此。

任何可能阻止手势选择器在UIImageView上触发的想法?词典?在游戏循环中不断更新有什么关系?任何想法都会受到欢迎,这似乎很容易实现......

编辑:这是UIImageView的代码以及我正在做的事情......不确定这是否有帮助。

扩展UIImageView类Paper.m(prp是用于初始化自定义变量的属性的struct

NSString *tName =  [NSString stringWithUTF8String: prp.imagePath];
UIImage *tImage = [UIImage imageNamed:[NSString stringWithFormat:@"%@.png",tName]];
self = [self initWithImage: tImage];
self.userInteractionEnabled = YES;
self.multipleTouchEnabled = YES;
self.center = CGPointMake(prp.spawnX, prp.spawnY);
if (prp.zPos != 0)  { self.layer.zPosition = prp.zPos; }
// other initialization excised

然后我有一个名为ObjManager的自定义类,它包含NSMutableDictionary并初始化所有UIImageView对象,其中addObj在循环中被调用以添加每个对象:

- (ObjManager*) initWithBlank {
    // create an array for our objects
    self = [super init];
    if (self) {
        objects = [[NSMutableDictionary alloc] init];
        spawnID = 100;  // start of counter for dynamically spawned object IDs
    }
    return self;
}

- (void) addObj:(Paper *)paperPiece wasSpawned:(BOOL)spawned {
    // add each paper piece, assign spawnID if dynamically spawned
    NSNumber *newID;
    if (spawned) { newID = [NSNumber numberWithInt:spawnID]; spawnID++; }
    else         { newID = [NSNumber numberWithInt:paperPiece.objID]; }
    [objects setObject:paperPiece forKey:newID];
}

我的视图控制器调用ObjManager的初始化(在我的VC中称为_world)。然后它像这样循环通过_world:

// Populate additional object managers and add all subviews
for (NSNumber *key in _world.objects) {

    _eachPiece = [_world.objects objectForKey:key];

    // Populate collision object manager
    if (_eachPiece.collision) {
        [_world_collisions addObj:_eachPiece wasSpawned:NO];
    }

    // only add pinch gesture if the object flag is set
    if (_eachPiece.pinch) {  
        UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchPaper:)];
        pinchGesture.delegate = self;
        [_eachPiece addGestureRecognizer:pinchGesture];
        NSLog(@"Added pinch recognizer scale: %@", pinchGesture.view.description);
    }

    // Add each object as a subview
    [self.view addSubview:_eachPiece];

}

_eachPiece是我的视图控制器中的一个对象,在.h文件中声明(就像_world一样):

@property (nonatomic, strong) ObjManager *world; 
@property (nonatomic, strong) Paper *eachPiece;

然后我有一个NSTimer对象,每隔一帧更新_world(ObjManager)中所有可移动的Paper对象(UIImageViews):

// loop through each piece and update
for (NSNumber *key in _world.objects) {

    eachPiece = [_world.objects objectForKey:key];

    // only update moveable pieces
    if ((eachPiece.moveType == Move_Touch) || (eachPiece.moveType == Move_Auto)) {

        CGPoint paperCenter;
        paperCenter = eachPiece.center;

        // a bunch of code to update paperCenter x & y for the object's new position based on velocity and user input

        // determine image direction and transformation matrix
        [_world updateDirection:eachPiece];
        CGAffineTransform transformPiece = [_world imageTransform:eachPiece];
        if (transformEnabled) {
            eachPiece.transform = transformPiece;
        }

        // finally move it
        [eachPiece setCenter:paperCenter];

    }

}

捏取选择器:

- (void)pinchPaper:(UIPinchGestureRecognizer *)recognizer {
    NSLog(@"Pinch scale: %f", recognizer.scale);
    recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, recognizer.scale);
    recognizer.scale = 1;
}

据我所知,捏应该有效。如果我采用相同的捏手势代码并将其设置为添加到视图控制器,则它适用于整个视图。我还有一个自定义的UIView类,它充当边框(只是一个围绕视图绘制的矩形),并且将夹点手势代码移动到那里只允许我捏住边框。

2 个答案:

答案 0 :(得分:2)

好吧,显然手势识别器不会触发位置动画的视图。因此,为了使其工作,我必须将识别器放在视图控制器上,然后执行命中测试并对触摸的视图应用捏合/缩放,如果它是我想要捏合/缩放的那个。关于这方面的信息:

http://iphonedevsdk.com/forum/iphone-sdk-tutorials/100982-caanimation-tutorial.html

就我的具体情况而言,我在视图控制器级别的变量/数组中跟踪了我想要捏合的动画视图。然后我在选择器中使用了这个代码(主要来自上面的链接,所有信用都是它们):

- (void)pinchPaper:(UIPinchGestureRecognizer *)recognizer {

    CALayer *pinchLayer;
    id layerDelegate;
    CGPoint touchPoint = [recognizer locationInView:self.view];

    pinchLayer = [self.view.layer.presentationLayer hitTest: touchPoint];
    layerDelegate = [pinchLayer delegate];

    //_pinchView is the UIView I want to pinch
    if (layerDelegate == _pinchView) {
        _pinchView.transform = CGAffineTransformScale(_pinchView.transform, recognizer.scale, recognizer.scale);
        recognizer.scale = 1;
    }
}

唯一棘手的事情是,如果您在现有UIView动画中进行其他比例变换(例如更改我的方向),则必须通过在每个更新循环期间使用当前变换来解释这一点。

答案 1 :(得分:1)

对于任何处理imageViews的手势识别器,必须在其上启用userInteraction。

所以,它应该是,

yourImageView.userInteractionEnabled = YES;

或者,如果您使用的是故事板,则可以在storyboard的检查器窗口中检查该选项。

希望它有所帮助.. :)