Добавляем Parallax эффект в iOS 7

Это оказалось настолько просто, что даже смешно:)

UIInterpolatingMotionEffect *xAxis = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
    xAxis.minimumRelativeValue = [NSNumber numberWithFloat:10.0];
    xAxis.maximumRelativeValue = [NSNumber numberWithFloat:-10.0];
UIInterpolatingMotionEffect *yAxis = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y" type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];
    yAxis.minimumRelativeValue = [NSNumber numberWithFloat:10.0];
    yAxis.maximumRelativeValue = [NSNumber numberWithFloat:-10.0];
UIMotionEffectGroup *group = [[UIMotionEffectGroup alloc] init];
    group.motionEffects = @[xAxis, yAxis];
    
[obj addMotionEffect:group];

добавляем группу на нужные объекты и все.

Для большего эффекта можно добавить обратные значения и прикрепить новую группу к заднему фону. В таком случае, объекты на переднем плане будут двигаться в противоположную сторону от фона.

Добавляем к Long Press Gesture Recognizer drag’n’drop

Вот выдержка из документации по UILongPressGestureRecognizer:

Long-press gestures are continuous. The gesture begins (UIGestureRecognizerStateBegan) when the number of allowable fingers (numberOfTouchesRequired) have been pressed for the specified period (minimumPressDuration) and the touches do not move beyond the allowable range of movement (allowableMovement). The gesture recognizer transitions to the Change state whenever a finger moves, and it ends (UIGestureRecognizerStateEnded) when any of the fingers are lifted.

Таким образом всю логику по передвижению view можно вставить в UIGestureRecognizerStateChanged.

- (void)longPressDetected:(UILongPressGestureRecognizer*)sender
{
    if (sender.state == UIGestureRecognizerStateBegan)
    {
        [UIView animateWithDuration:0.2 animations:^{
          sender.view.transform = CGAffineTransformMakeScale(1.3, 1.3);
        }];
    }
    else if (sender.state == UIGestureRecognizerStateChanged)
    {        
        CGFloat finalX = [sender locationInView:self].x;
        CGFloat finalY = [sender locationInView:self].y;
        
        int border = 60;

        if (finalX < CGRectGetMinX(self.bounds) + border)
            finalX = CGRectGetMinX(self.bounds) + border;
        else if (finalX > CGRectGetMaxX(self.bounds) - border)
            finalX = CGRectGetMaxX(self.bounds) - border;

        if (finalY < CGRectGetMinY(self.bounds) + border)
            finalY = CGRectGetMinY(self.bounds) + border;
        else if (finalY > CGRectGetMaxY(self.bounds) - border)
            finalY = CGRectGetMaxY(self.bounds) - border;
        
        
        sender.view.center = CGPointMake(finalX, finalY);
    }
    else if (sender.state == UIGestureRecognizerStateEnded)
    {
        [UIView animateWithDuration:0.2 animations:^{
          sender.view.transform = CGAffineTransformMakeScale(1.0, 1.0);
        }];
    }
}

почему-то я раньше не обращал на это внимание и делал это двумя разными рекогнайзерами… 

Быстрое удаление Derived Data

Deisa Mason сделала отличный плагин для Xcode, позволяющий одной кнопкой быстро удалить Derived Data из проекта. Это достаточно просто сделать и с помощью терминала, но так, безусловно, быстрее.

Инструкция по установке.