swift: сглаживание перевода UIView точно так же, как панель управления iOS (следуя пальцу пользователя, используя панорамирование) - PullRequest
0 голосов
/ 11 мая 2019

Я хочу переместить UIView снизу вверх пальцем, точно так же, как центр управления в iOS, и особенно с тем же «сглаживанием» движения, что и центр управления в iOS (скорость выглядит ограниченной, когда скорость высокая, нет нужно далеко ходить пальцем, чтобы UIView переместился наверх и т. д.). Мой вопрос: есть ли какой-нибудь пресет или библиотека, которые я мог бы использовать вместо того, чтобы делать свои собственные и не точные вычисления сам? Я не очень хорош в создании этого "гладкого" эффекта, и, возможно, UIKit предоставляет что-то, что можно использовать в обработчике panGestureRecognizer для сглаживания трансляции движения после sender.translation?

Теперь мой обработчик жеста-распознавателя:

var y = sender.translation(in: view).y
let vy = sender.velocity(in: view).y

// we need to move constraintHeightInfoView.constant
// this is the height of my "ios control panel"

// i noticed the ios control panel move less if user tries 
// to move it out of screen bounds, so i'm first calculating 
// how much we are out of bound, in order to know "how much" 
// we will reduce velocity
var outofbound:CGFloat = 0
if(constraintHeightInfoView.constant < minH)
{
    outofbound = minH - constraintHeightInfoView.constant
}
else if(constraintHeightInfoView.constant > maxH)
{
    outofbound = constraintHeightInfoView.constant - maxH
}

// velocity target in pt/s
// i noticed the smooth effect in ios control panel includes 
// a velocity bound : if user pulls very fast the control panel, 
// it is not following the user finger, but it's a bit slower : 
// so there is a "vmax". When user release, i guess this vmax is 
// used for the final animation too 
let vtarget:CGFloat = 300 

print("\(y), \(vy), ofb : \(outofbound)")


// Here i'm lost : im trying to say : 
// if velocity above vtarget, reduce y so it match vtarget
if(abs(vy) > vtarget) {
    let dv = abs(vy) - vtarget
    y = // ????
}





switch sender.state {
    case .began, .changed :
    if case .began = sender.state {
        initialY = constraintHeightInfoView.constant
    }

    let newH = (expandInfoViewInitialY ?? minH) - y

    constraintHeightInfoView.constant = newH

    view.layoutIfNeeded()

case .ended :

    let heightTo:CGFloat
    let blurAlpha:CGFloat
    // 250 is the middle between top position and 
    // bottom position : if velocity is high, dont need to pull 
    // a lot to proceed the final release animation
    // if vy is 3000, even very small movement proceed the 
    // animation. Otherwise, if very slow movement, 
    // user needs to go at least at the middle between top and bottom (250)
    if(constraintHeightInfoView.constant > 250 - (-vy/300) * 50)
    {
        heightTo = maxH
        blurAlpha = 1
    }
    else
    {
        heightTo = minH
        blurAlpha = 0
    }


    // time of animation depends on remaining distance to bottom/top
    let dy = abs(self.constraintHeightInfoView.constant - heightTo)


    var t = dy / vtarget

    print("end : d:\(dy), t:\(t)")
    UIView.animate(withDuration:TimeInterval(t), delay:0,options:[.curveEaseOut], animations :{
        self.constraintHeightInfoView.constant = heightTo
        self.viewInfoBlurEffect.alpha = blurAlpha
        self.view.layoutIfNeeded()
    })

default :
    break
}

Несмотря на все это, мой переход все еще далек от того, чтобы выглядеть как переход центра управления Apple ...

1 Ответ

1 голос
/ 11 мая 2019

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

Это позволит вам, например, просто «закончить» анимацию, если пользователь перетаскивает больше определенного количества. И вы сможете выполнять как касание к увольнению, так и перетаскивание с помощью одного и того же аниматора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...