문제

I have an app where the user taps a button and the app will instantiate an image layer (UIImageView). I want to make it so that the user can move the selected image layer whichever they tap. After reading some topics here, I've learnt that I can use UIPanGestureRecognizer to move the selected image layer.

- (IBAction)buttonClicked:(id)sender {
    imageview = [[UIImageView alloc] initWithFrame:CGRectMake(100, 0, 300, 22)];
    UIPanGestureRecognizer *imageviewGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(recognizePan:)];
    [imageviewGesture setMinimumNumberOfTouches:1];
    [imageviewGesture setMaximumNumberOfTouches:1];
    imageview.image = [UIImage imageNamed:@"pinimage.png"];
    [imageview addGestureRecognizer:imageviewGesture];
    [imageview setUserInteractionEnabled:YES];
    [self.view addSubview:imageview];
    NSUInteger currentag = [self UniqueTag]; // Assigning a unique integer
    imageview.tag = currentag;
}

- (void)recognizePan:(UIPanGestureRecognizer *)sender {
    [[[(UITapGestureRecognizer *)sender view] layer] removeAllAnimations];
    [self.view bringSubviewToFront:[(UIPanGestureRecognizer *)sender view]];
    CGPoint translatedPoint = [(UIPanGestureRecognizer *)sender translationInView:self.view];

    if([(UIPanGestureRecognizer *)sender state] == UIGestureRecognizerStateBegan) {     
        firstX = [[sender view] center].x;
        firstY = [[sender view] center].y;
    }

    translatedPoint = CGPointMake(firstX + translatedPoint.x,firstY + translatedPoint.y);
    [[sender view] setCenter:translatedPoint];
}

Now, what I cannot figure out is how to bring the tapped layer to front when there are multiple image layers. It doesn't seem that [self.view bringSubviewToFront:[(UIPanGestureRecognizer *)sender view]] is effective. So how can I revise my code so that the application will bring the tapped layer to the top among others?

Thank you for your help.

도움이 되었습니까?

해결책

A good way to do this is to make a CustomImageView subclass of UIImageView. You attach the UIPanGestureRecognizer to each instance of CustomImageView, and set that instance as it's target. Then the action method triggered by the gesture is implemented in the view itself, so that you can refer to the view with self:

In buttonClicked

    MyImageView* imageview = [[MyImageView alloc] initWithFrame:CGRectMake(100, 0, 300, 22)];
    UIPanGestureRecognizer *imageviewGesture = 
    [[UIPanGestureRecognizer alloc] initWithTarget:imageview 
                                            action:@selector(recognizePan:)];

In CustomImageView.m

    - (void)recognizePan:(UIPanGestureRecognizer *)sender {
        [self.layer removeAllAnimations];
        [self.superview bringSubviewToFront:self];
        CGPoint translatedPoint = [sender translationInView:self];
        if([sender state] == UIGestureRecognizerStateBegan) {
            self.firstX = [self center].x;
            self.firstY = [self center].y;
        }
        translatedPoint = CGPointMake(self.firstX + translatedPoint.x,
                                      self.firstY + translatedPoint.y);
        [self setCenter:translatedPoint];
    }

update

Not thinking straight - you can of course do this from the viewController, as you are doing, by accessing the view property of the gestureRecongnizer. Your error is rather here:

- (void)recognizePan:(UIPanGestureRecognizer *)sender {
     [[[(UITapGestureRecognizer *)sender view] layer] removeAllAnimations];

You are changing the sender type from UIPanGestureRecognizer to UITapGestureRecognizer. In fact you don't need to do any of that sender typecasting in the body of the method.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top