0

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

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

我的 UIImageViews 存储在 NSMutableDictionary 中,并在游戏的每个更新循环期间通过循环进行更新。这会对不调用 UIPinchGestureRecognizer 产生影响吗?...我想不出其他任何东西,发布代码可能无济于事 - 因为相同的代码在用于 UIView 或视图控制器时有效。

我在视图控制器的 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 类,它充当边框(只是在视图周围绘制一个矩形),并将捏合手势代码移动到该类允许我只捏合边框。

4

2 回答 2

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 动画中进行了其他缩放变换(例如我的方向更改),则必须通过在每个更新循环期间使用当前变换来解决此问题。

于 2012-12-11T06:24:54.373 回答
1

要让任何手势识别器在 imageViews 上工作,必须在其上启用 userInteraction。

所以,应该是,

yourImageView.userInteractionEnabled = YES;

或者,如果您正在使用情节提要,您也可以在情节提要的检查器窗口中检查该选项。

希望能帮助到你..:)

于 2012-12-03T09:37:26.023 回答