Tengo una vista que sirve como contenedor para otras 2 vistas (una vista que ocupa 1/4 de la pantalla y una vista de tabla que ocupa 3/4 de la pantalla). Lo que quiero es que cuando el usuario se desplace hacia arriba (dirección de deslizamiento) en la vista de la tabla, la vista de la tabla suba suavemente (hasta la pantalla) y baje cuando los usuarios se desplacen hacia abajo (dirección de deslizamiento).

Hasta ahora me las he arreglado para que la vista de tabla suba, pero lo hace demasiado repentinamente y no puedo hacer que baje. Así es como lo hago: viewViewTopConstraint es la restricción superior de la vista de tabla a la restricción superior del contenedor

extension StatsOverlayViewController: UIScrollViewDelegate {
func scrollViewDidScroll(scrollView: UIScrollView) {
    if scrollView == statsTableView {
        let scrolledOffset = scrollView.contentOffset.y

        while viewViewTopConstraint.constant > 0  && viewViewTopConstraint.constant < 69 {
            print("scrolling with offset\(scrollView.contentOffset.y)")
                self.viewViewTopConstraint.constant -= scrolledOffset
        }
    }
}

func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    if scrollView == statsTableView {
        if  viewViewTopConstraint.constant < 0 {
            viewViewTopConstraint.constant = 0
        } else if viewViewTopConstraint.constant > 69 {
            viewViewTopConstraint.constant = 69
        }
    }
}

}

Editar:

El problema al volver a bajar la vista se debió a scrollview.bounces = true y al uso incorrecto del código while del bucle que funciona es:

       func scrollViewDidScroll(scrollView: UIScrollView) {
    if scrollView == statsTableView {
        let scrolledOffset = scrollView.contentOffset.y
        UIView.animateWithDuration(0.2, animations: {
            if scrolledOffset > 0 {
                self.viewViewTopConstraint.constant = 0
            } else {
                self.viewViewTopConstraint.constant = self.viewViewTopConstraintOriginalValues
            }
            self.view.layoutIfNeeded()
        })
    }
}
0
anho 11 ene. 2017 a las 20:04

1 respuesta

La mejor respuesta

Debes llamar a self.view.layoutIfNeeded dentro del bloque UIView.animate

UIView.animate(withDuration: 1) { 
    self.view.layoutIfNeeded
}

Agregue este código justo después de cambiar su restricción. Si quieres un poco más de control sobre tu animación, usa este

UIView.animate(withDuration: 1, delay: 0, options: [.curveEaseInOut], animations: {
    self.view.layoutIfNeeded
}, completion: nil)
1
ebby94 11 ene. 2017 a las 20:22
1
¿No es una buena práctica llamar a cualquier cambio de restricción dentro del bloque de animación en sí, no fuera de él?
 – 
Pierce
11 ene. 2017 a las 20:48
Gracias, esto hace que la animación sea un poco más agradable pero aún no resuelve el problema de desplazamiento hacia abajo
 – 
anho
11 ene. 2017 a las 22:11
Incluso después de cambiar la restricción, el diseño se actualizará solo si se llama a layoutIfNeeded, por lo que no creo que haya mucha diferencia. Cuando cambiamos el valor constante de la restricción, llama a layoutIfNeeded, que es la razón por la que el cambio no estaba animado.
 – 
ebby94
12 ene. 2017 a las 06:17