UIPanGestureRecognizer и BringSubviewToFront

У меня есть приложение, в котором пользователь нажимает кнопку, и приложение создает экземпляр слоя изображения (UIImageView). Я хочу сделать так, чтобы пользователь мог перемещать выбранный слой изображения в зависимости от того, на что он нажимает. Прочитав некоторые темы здесь, я узнал, что могу использовать UIPanGestureRecognizer для перемещения выбранного слоя изображения.

- (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];
}

Теперь я не могу понять, как вывести слой с постукиванием на передний план, когда есть несколько слоев изображения. Не похоже, что [self.view BringSubviewToFront: [(UIPanGestureRecognizer *) представление отправителя]] эффективен. Итак, как я могу пересмотреть свой код, чтобы приложение выводило нажатый слой наверх среди других?

Спасибо за помощь.


person El Tomato    schedule 13.04.2013    source источник


Ответы (1)


Хороший способ сделать это — создать подкласс CustomImageView для UIImageView. Вы прикрепляете UIPanGestureRecognizer к каждому экземпляру CustomImageView и устанавливаете этот экземпляр в качестве цели. Затем метод действия, запускаемый жестом, реализуется в самом представлении, так что вы можете ссылаться на представление с помощью 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];
    }

обновить

Не думая прямо - вы, конечно, можете сделать это из viewController, как вы это делаете, обратившись к свойству view жестового Recongnizer. Ваша ошибка скорее здесь:

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

Вы меняете тип отправителя с UIPanGestureRecognizer на UITapGestureRecognizer. На самом деле вам не нужно делать ничего из этого sender приведения типов в теле метода.

person foundry    schedule 14.04.2013
comment
@TBlue, вы совершенно правы, я не сразу подумал ... но все же остается вопрос, почему у вас не работает? Мой работает, и он в основном выполняет ту же работу, что и ваш... - person foundry; 14.04.2013
comment
Спасибо. Это следует исправить. На самом деле, то, что я опубликовал, кажется, работает с опечаткой или без нее. Ошибка, которую я сделал, которая не очевидна в моем коде, заключается в том, что я включил TextView сразу после [self.view addSubview:imageview]. Думаю, это портит дело. - person El Tomato; 14.04.2013