ios - constraint - uiview animate position
UIView.animateWithDuration Not Animating Swift(otra vez) (9)
Nota: ya he comprobado los siguientes problemas de desbordamiento de pila:
27907570 , 32229252 , 26118141 , 31604300
Todo lo que estoy tratando de hacer es desvanecerse animado en una vista (por alfa) cuando es llamado por una acción IBA adjunta a un botón. Luego retroceda cuando se golpea un botón en la vista.
Mi arruga puede ser que estoy usando una vista secundaria que está en el ViewDock en la vista del guión gráfico. La vista se agrega a la subvista en el momento de viewDidLoad donde el marco / los límites se configuran de la misma forma que la vista de supervisión (para una parada completa)
La razón por la que esto se hace como una vista de superposición, ya que es un indicador tutorial.
El resultado (como muchos otros que han enumerado este problema) es que la vista (y los controles contenidos) simplemente aparecen instantáneamente y desaparecen instantáneamente. No se desvanecen.
He intentado la animación con la duración con retraso, con y sin completar, con la transición, e incluso comencé con el antiguo UIView.beginAnimations.
Nada está funcionando. Sugerencias de bienvenida.
El código es tan sencillo como puedo hacerlo:
Editar: Expandió el código a todo lo relevante
Edit2: TL; DR Todo funciona con la excepción de UIViewAnimateWithDuration, que parece ignorar el bloqueo y la duración y simplemente ejecuta el código en línea como un cambio inmediato de la interfaz de usuario. Resolviendo esto se obtiene la recompensa.
@IBOutlet var infoDetailView: UIView! // Connected to the view in the SceneDock
override func viewDidLoad() {
super.viewDidLoad()
// Cut other vDL code that isn''t relevant
setupInfoView()
}
func setupInfoView() {
infoDetailView.alpha = 0.0
view.addSubview(infoDetailView)
updateInfoViewRect(infoDetailView.superview!.bounds.size)
}
func updateInfoViewRect(size:CGSize) {
let viewRect = CGRect(origin: CGPointZero, size: size)
infoDetailView.frame = viewRect
infoDetailView.bounds = viewRect
infoDetailView.layoutIfNeeded()
infoDetailView.setNeedsDisplay()
}
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
updateInfoViewRect(size)
}
func hideInfoView() {
AFLog.enter(thisClass)
UIView.animateWithDuration(
2.0,
animations:
{
self.infoDetailView.alpha = 0.0
},
completion:
{ (finished) in
return true
}
)
AFLog.exit(thisClass)
}
func showInfoView() {
AFLog.enter(thisClass)
UIView.animateWithDuration(
2.0,
animations:
{
self.infoDetailView.alpha = 0.75
},
completion:
{ (finished) in
return true
}
)
AFLog.exit(thisClass)
}
// MARK: - IBActions
@IBAction func openInfoView(sender: UIButton) {
showInfoView()
}
@IBAction func closeInfoView(sender: UIButton) {
hideInfoView()
}
Tenga en cuenta que empecé con lo siguiente:
func showInfoView() {
UIView.animateWithDuration(2.0, animations: { () -> Void in
self.infoDetailView.alpha = 0.75
})
}
func hideInfoView() {
UIView.animateWithDuration(2.0, animations: { () -> Void in
self.infoDetailView.alpha = 0.00
})
}
¿Ha intentado cambiar su showInfoView()
a algo más como toggleInfoView
?
func toggleInfoView() {
let alpha = CGFloat(infoDetailView.alpha == 0 ? 1 : 0)
infoDetailView.alpha = alpha //this is where the toggle happens
}
Dice que si el alfa de su vista es 0, cámbielo a 1. Si no, haga que sea 0.
Si necesitas que eso suceda en una animación, prueba
@IBAction func openInfoView(sender: UIButton) {
UIView.animate(withDuration: 2.0, animations: {
self.toggleInfoView() //fade in/out infoDetailView when animating
})
}
- Aún querrá mantener ese
infoDetailView.alpha = 0.0
donde lo tenga, proveniente deviewDidLoad
.
Asegúrese de que el opaque
infoDetailView
sea falso.
Esta propiedad proporciona una sugerencia al sistema de dibujo en cuanto a cómo debe tratar la vista. Si se establece en verdadero, el sistema de dibujo considera la vista como totalmente opaca, lo que permite al sistema de dibujo optimizar algunas operaciones de dibujo y mejorar el rendimiento. Si se establece en falso, el sistema de dibujo compone la vista normalmente con otro contenido. El valor predeterminado de esta propiedad es verdadero.
Hay varias cosas extrañas que puedo ver,
primero, retire:
infoDetailView.layoutIfNeeded()
infoDetailView.setNeedsDisplay()
Por lo general, no necesita llamar a esos métodos manualmente a menos que sepa exactamente lo que está haciendo.
Además, cuando estás cambiando el tamaño:
infoDetailView.frame = viewRect
infoDetailView.bounds = viewRect
Nunca es necesario establecer ambos bounds
y frame
. Sólo establece el frame
.
Además, probablemente deberías asegurarte de que la vista en realidad no ignore el marco al configurar:
infoDetailView.translatesAutoresizingMaskIntoConstraints = true
En lugar de restablecer el marco, simplemente configure la máscara de tamaño automático:
infoDetailView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
Resultando en:
override func viewDidLoad() {
super.viewDidLoad()
// Cut other vDL code that isn''t relevant
setupInfoView()
}
func setupInfoView() {
infoDetailView.alpha = 0.0
infoDetailView.translatesAutoresizingMaskIntoConstraints = true
infoDetailView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
infoDetailView.frame = view.bounds
view.addSubview(infoDetailView)
}
func hideInfoView() {
...
}
Creo que esto realmente debería ayudar porque las animaciones inmediatas a menudo están conectadas a problemas de tamaño.
Si el problema persiste, debe verificar si el infoDetailView
en su animación es el mismo objeto que el infoDetailView
que está agregando al controlador.
He replicado tu código y funciona bien, todo está bien. Probablemente debe controlar las restricciones, las conexiones de IBOutlet y IBActions. Intente aislar este código en un nuevo proyecto si es necesario.
Actualización : mi código y mi storyboard y foto de carpeta de proyecto:
Cada objeto (vista y botones) tiene la configuración predeterminada.
He comentado todas las líneas de AFLog (es probable que solo haya más "modo detallado" para ayudarlo), el resto de su código está bien y hace lo que se le mostró, si presiona el botón para abrir la vista, y cuando se toca el botón de cerrar, la vista se desvanece.
PS No es relevante pero estoy usando xCode 7.3, un nuevo proyecto swift 2.2.
Intenta debajo del código. Solo juega con alfa y tiempo de duración para perfeccionarlo.
Ocultar func
func hideInfoView() {
AFLog.enter(thisClass)
UIView.animateWithDuration(
2.0,
animations:
{
self.infoDetailView.alpha = 0.8
},
completion:
{ (finished) in
UIView.animateWithDuration(
2.0,
animations:
{
self.infoDetailView.alpha = 0.4
},
completion:
{ (finished) in
self.infoDetailView.alpha = 0.0
}
)
}
)
AFLog.exit(thisClass)
}
Mostrar func
func showInfoView() {
AFLog.enter(thisClass)
UIView.animateWithDuration(
2.0,
animations:
{
self.infoDetailView.alpha = 0.3
},
completion:
{ (finished) in
UIView.animateWithDuration(
2.0,
animations:
{
self.infoDetailView.alpha = 0.7
},
completion:
{ (finished) in
self.infoDetailView.alpha = 1.0
}
)
}
)
AFLog.exit(thisClass)
}
Para el componente UILabel, intente cambiar el color de fondo de la capa en su lugar.
Prueba esto (Probado en Swift 4):
UIView.animate(withDuration: 0.2, animations: {
self.dateLabel.layer.backgroundColor = UIColor.red.cgColor;
})
Si infoDetailView está bajo restricciones de diseño automático, debe llamar a layoutIfNeeded en la vista principal dentro de animateWithDuration:
func showInfoView() {
self.view.layoutIfNeeded() // call it also here to finish pending layout operations
UIView.animateWithDuration(2.0, animations: { () -> Void in
self.infoDetailView.alpha = 0.75
self.view.layoutIfNeeded()
})
}
Teóricamente, esto no debería ser necesario si solo cambia el valor de .alpha, pero quizás este podría ser el problema en este caso.
Si la animación no parece ejecutarse, entonces considere examinar el estado de cada una de sus vistas, antes de ingresar al bloque de animación. Por ejemplo, si el alfa ya está establecido en 0.4, la animación que ajusta su vista alfa se completará casi instantáneamente, sin efecto aparente.
Considere el uso de una animación de fotogramas clave en su lugar. Así es como se ve una animación de shake en el objetivo c.
+(CAKeyframeAnimation*)shakeAnimation {
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
animation.values = @[[NSValue valueWithCATransform3D:CATransform3DMakeTranslation(-10.0, 0.0, 0.0)],
[NSValue valueWithCATransform3D:CATransform3DMakeTranslation(10.0, 0.0, 0.0)]];
animation.autoreverses = YES;
animation.repeatCount = 2;
animation.duration = 0.07;
return animation;
}
Aquí hay una publicación que muestra cómo ajustar alfa con fotogramas clave https://.com/a/18658081/1951992
Usa este código:
UIView.animateWithDuration(0.3, animations: { () -> Void in
self.infoDetailView.alpha = 0.0
})