Вопрос по ios – Как переворачивать неэкранные UIView в суперпредставлении с закругленными углами?

2

Я переворачиваю UIViews, похожие на перелистывание страниц приложения Погода. Представления не являются полноэкранными, хотя, а суперпредставление имеет закругленные углы. Проблема заключается в том, что во время анимации переворота закругленные углы суперпредставления заполняются до квадратных углов черным.

Вот как я устанавливаю углы:

self.view.layer.cornerRadius = 15.0f;
self.view.clipsToBounds = YES;

Вот как я переворачиваю взгляды (обаfrontView а такжеbackView сохраняются):

UIView *toView;
UIView *fromView;
UIViewAnimationOptions animationType;

if (toFront) {
    toView = self.frontView;
    fromView = self.backView;
    animationType = UIViewAnimationOptionTransitionFlipFromLeft;
} else {
    toView = self.backView;
    fromView = self.frontView;
    animationType = UIViewAnimationOptionTransitionFlipFromRight;
}

[UIView transitionFromView:self.fromView
                    toView:self.toView
                  duration:1
                   options:animationType
                completion:nil];

Когда я делаю это,self.viewкруглые углы заполнены до их прямоугольных угловых краев черным. Можно ли этого избежать? Я не думаю, что знаю достаточно о базовой анимации, чтобы решить эту проблему.

Насколько мне известно, CA работает с "снимком" самого объекта пользовательского интерфейса вместо реального объекта ... CodaFi
Похоже, что во время анимации виды становятся непрозрачными (без прозрачности). Это объясняет, почему их прозрачные области заполняются черным. David Rönnqvist

Ваш Ответ

2   ответа
5

вы должны сделать это, создав анимацию отдельно от замены видов. Это не невозможно сложно. Описание того, как это сделать, и пример кода приведен ниже:

Замена взглядов

Замена представлений может быть сделана, например, с помощью:

[UIView transitionFromView:self.fromView
                    toView:self.toView
                  duration:0.0
                   options:UIViewAnimationOptionTransitionNone
                completion:nil];
Анимация сальто

Сложная часть - это, очевидно, анимация (и соединение обоих, если вы никогда не делали этого раньше

Только показ передней части обоих видов

Так как вы хотите перевернуть два вида, как если бы они были двумя сторонами листа бумаги, вы не хотите, чтобы один из них появлялся, когда они смотрят в сторону. Это делается путем установкиdoubleSided свойствоNO наи то и друго слои. (не быть двусторонним означает быть односторонним).

Делаем бросок

Вы хотите анимировать преобразование вида спереди от преобразования идентичности (без преобразования) до преобразования с поворотом на 180 градусов (обращенного назад) вокруг оси y, чтобы оно переворачивало форму слева направо.

В то же время вы хотите анимировать преобразование вида сзадио поворот на -180 градусов для преобразования личности. Это сделает обратный ход. Обе эти анимации могут быть выполнены как «основные» анимации:

CABasicAnimation *flipAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
[flipAnimation setFromValue:[NSValue valueWithCATransform3D:CATransform3DIdentity]]; // No rotation
[flipAnimation setToValue:[NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI, 0,1,0)]]; // Rotate PI around Y
[flipAnimation setFillMode:kCAFillModeBoth];
[flipAnimation setRemoveOnCompletion:NO];
[flippingView layer] addAnimation:flipAnimation forKey:@"myFlipAnimation"];

Затем вы делаете такую же анимацию для другого вида. (Режим заполнения предотвращает возврат анимации к исходному состоянию после завершения).

Собираем все вместе

Так как вы хотите, чтобы обе анимации запускались одновременно, и чтобы ваш замещающий код код запускался после завершения анимации, вы можете использовать транзакцию анимации. Это также позволит вам настроить внешний вид обеих анимаций в одном месте:

[CATransaction begin];
[CATransaction setAnimationDuration:2.0]; // 2 seconds
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[CATransaction setCompletionBlock:^{
    // Your view replacing code here...
}];
// Add the animations to both views here...
[CATransaction commit];
Почему это необходимо? Например, почему возникает такая проблема (о которой говорил OP) при анимации UIView? kgaidis
0

работает нормально, но, конечно, проверьте это сами.

Стоит отметить:

Перед вызовом этого метода вы должны добавить представление, для которого вы анимируете.

Метод НЕ удаляет ни одно из представлений, поэтому при необходимости удалите их с блоком завершения.

Метод также не изменяет значения «модели слоя» ваших представлений, поэтому они останутся такими же, какими они были после анимации.

`

+ (void)flipRight:(BOOL)flipRight fromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration completion:(void (^)(void))completionBlock {

// Save original values
BOOL fromViewDoubleSided = fromView.layer.doubleSided;
BOOL toViewDoubleSided = toView.layer.doubleSided;
BOOL fromViewUserInteractionEnabled = fromView.userInteractionEnabled;
BOOL toViewUserInteractionEnabled = toView.userInteractionEnabled;

// We don't want to see the other side of the layer
fromView.layer.doubleSided = NO;
toView.layer.doubleSided = NO;

// We don't want user to fire off animation while its already going
fromView.userInteractionEnabled = NO;
toView.userInteractionEnabled = NO;

[CATransaction begin];

[CATransaction setCompletionBlock:^{

    // Restore original values
    fromView.layer.doubleSided = fromViewDoubleSided;
    toView.layer.doubleSided = toViewDoubleSided;
    fromView.userInteractionEnabled = fromViewUserInteractionEnabled;
    toView.userInteractionEnabled = toViewUserInteractionEnabled;

    if (completionBlock) completionBlock();
}];

CATransform3D flipOutTransform3D = CATransform3DMakeRotation(M_PI, 0,1,0);
flipOutTransform3D.m34 = 1.0/(300.0*(flipRight ? -1 : 1));
CABasicAnimation *flipOutAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
flipOutAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
flipOutAnimation.toValue = [NSValue valueWithCATransform3D:flipOutTransform3D];
flipOutAnimation.duration = duration;

CATransform3D flipInTransform3D = CATransform3DMakeRotation(M_PI, 0,1,0);
flipInTransform3D.m34 = 1.0/(300.0*(flipRight ? 1 : -1));
CABasicAnimation *flipInAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
flipInAnimation.fromValue = [NSValue valueWithCATransform3D:flipInTransform3D];
flipInAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
flipInAnimation.duration = duration;


[fromView.layer addAnimation:flipOutAnimation forKey:@"flipOutAnimation"];
[toView.layer addAnimation:flipInAnimation forKey:@"flipInAnimation"];

[CATransaction commit];
};

Похожие вопросы