Двухсторонний UIView не работает
У меня есть подкласс UIView
называется TitleView
все, что делает этот подкласс - это переопределение layerClass
возвращать CATransformLayer
,
мой titleView
у собственности есть некоторые подпредставления; titleBackgroundView
и titleLabel
,
Когда я запускаю свой код titleView
верхний слой виден (зеленый фон), но когда я запускаю анимацию сальто, анимация отсутствует. Код просто переходит в конечное состояние. Кроме того, нет видимого нижнего слоя (красный фон), только обратная версия titleView
(преобразованный titleLabel
).
В установщике IBOutlet у меня есть следующий код:
@IBOutlet private weak var titleView: TitleView! {
didSet {
titleView.backgroundColor = UIColor.clearColor()
let topLayer = CALayer()
topLayer.backgroundColor = UIColor.greenColor().CGColor
topLayer.frame = titleView.bounds
topLayer.doubleSided = false
topLayer.zPosition = 3
titleView.layer.addSublayer(topLayer)
let bottomLayer = CALayer()
bottomLayer.backgroundColor = UIColor.redColor().CGColor
bottomLayer.frame = titleView.bounds
bottomLayer.doubleSided = false
bottomLayer.zPosition = 2
bottomLayer.transform = CATransform3DMakeRotation(CGFloat(M_PI), 1, 0, 0)
titleView.layer.addSublayer(bottomLayer)
}
}
titleView
анимационный код:
private func setIsCategoriesShowing(showCategories: Bool, animated: Bool)
{
let alreadyInFinishState = (isShowingCategories == showCategories) ? true : false
if alreadyInFinishState
{
return
}
// Setup animations
isAnimatingCategories = true
headerView.superview?.bringSubviewToFront(headerView)
titleView.layer.setAnchorPointDynamically(CGPoint(x: 0.5, y: 1)) // Change position when updating anchor point
// Animate
let duration: NSTimeInterval = animated ? 0.8 : 0
let options: UIViewAnimationOptions = (showCategories == true) ? [.CurveEaseIn] : [.CurveEaseOut]
let newRotationValue: CGFloat = (showCategories == true) ? -179 : 0
let damping: CGFloat = (showCategories == true) ? 0.7 : 1
let initialSpringVelocity: CGFloat = (showCategories == true) ? 0.5 : 1
UIView.animateWithDuration(duration,
delay: 0,
usingSpringWithDamping: damping,
initialSpringVelocity: initialSpringVelocity,
options: options,
animations: { () -> Void in
var rotationAndPerspectiveTransform = CATransform3DIdentity
rotationAndPerspectiveTransform.m34 = 1 / -500
rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, newRotationValue, 1, 0, 0);
self.titleView.layer.sublayerTransform = rotationAndPerspectiveTransform;
}) { (success) -> Void in
if showCategories == false
{
self.titleView.layer.sublayerTransform = CATransform3DIdentity
}
self.isAnimatingCategories = false
self.isShowingCategories = showCategories
}
}
1 ответ
Итак, учитывая серию проб и ошибок, мне удалось (кажется) исправить мою проблему. Не стесняйтесь взглянуть...
Вот рабочий код:
@IBOutlet private weak var titleView: TitleView! {
didSet {
let bottomLayer = CALayer()
bottomLayer.backgroundColor = UIColor.redColor().CGColor
bottomLayer.frame = titleView.bounds
bottomLayer.doubleSided = false
bottomLayer.zPosition = 2
bottomLayer.transform = CATransform3DMakeRotation(CGFloat(M_PI), 0, 1, 0) // Reverse bottom layer, so when flipped it's visible.
titleView.layer.addSublayer(bottomLayer)
// All subviews are one-sided
for subview in titleView.subviews
{
subview.layer.doubleSided = false
}
}
}
@IBOutlet private weak var titleViewBackgroundView: UIView!
Код анимации:
private func setIsCategoriesShowing(showCategories: Bool, animated: Bool)
{
let alreadyInFinishState = (isShowingCategories == showCategories) ? true : false
if alreadyInFinishState
{
return
}
// Housekeeping
headerView.superview?.bringSubviewToFront(headerView)
titleView.layer.setAnchorPointDynamically(CGPoint(x: 0.5, y: 1))
// Animate
isAnimatingCategories = true
let isOpening = (showCategories == true)
let duration: NSTimeInterval = animated ? 3 : 0
let damping: CGFloat = isOpening ? 0.7 : 1
let initialSpringVelocity: CGFloat = isOpening ? 0.5 : 1
let options: UIViewAnimationOptions = isOpening ? [.CurveEaseIn] : [.CurveEaseOut]
let newRotationValue: CGFloat = isOpening ? -179 : 0
var rotationAndPerspectiveTransform = CATransform3DIdentity
rotationAndPerspectiveTransform.m34 = 1 / -500
rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, newRotationValue, 1, 0, 0);
UIView.animateWithDuration(duration,
delay: 0,
usingSpringWithDamping: damping,
initialSpringVelocity: initialSpringVelocity,
options: options,
animations: {
self.titleView.layer.transform = rotationAndPerspectiveTransform;
}) { (success) -> Void in
if !isOpening
{
self.titleView.layer.transform = CATransform3DIdentity
}
self.isAnimatingCategories = !success
self.isShowingCategories = showCategories
}
}