简体   繁体   中英

Autoscroll UIScrollView, allow user to interrupt animation

I'm trying to animate a bunch of images in a UIScrollView. The images should start scrolling when the screen shows, which I can do. At the moment I'm using UIView animations as follows:

    [Export("ScrollToRight")]
    private void ScrollRight()
    {
        if (!imagesShouldScroll)
            return;
        UIView.BeginAnimations("ScrollRight");
        UIView.SetAnimationCurve(UIViewAnimationCurve.Linear);
        UIView.SetAnimationDuration(test.Count * 10);
        scrlImages.ContentOffset = new PointF(((scrlImages.Frame.Height + 2) * test.Count) - scrlImages.Frame.Width, 0);
        UIView.SetAnimationDelegate(this);
        UIView.SetAnimationDidStopSelector(new Selector("ScrollToLeft"));
        UIView.CommitAnimations();
    }

    [Export("ScrollToLeft")]
    private void ScrollLeft()
    {
        if (!imagesShouldScroll)
            return;
        UIView.BeginAnimations("ScrollLeft");
        UIView.SetAnimationCurve(UIViewAnimationCurve.Linear);
        UIView.SetAnimationDuration(test.Count * 10);
        scrlImages.ContentOffset = new PointF(0, 0);
        UIView.SetAnimationDelegate(this);
        UIView.SetAnimationDidStopSelector(new Selector("ScrollToRight"));
        UIView.CommitAnimations();
    }

This works perfectly to scroll back and forth in the UIScrollView. What I need to be able to do is let the user interrupt the animation by swiping on the ScrollView as they would normally scroll through the list. So I have attached a listener to the ScrollView as follows:

        scrlImages.DraggingStarted += (sender, e) => 
        {
           if (imagesShouldScroll)
           {
               scrlImages.Layer.RemoveAllAnimations();
               imagesShouldScroll = false;
           }
        };

This works to stop the animations as expected. The problem is that the ContentOffset has already been set to the edge where it's busy animating to. So when the user swipes the ScrollView it suddenly jumps to the end of the list. I'd like the user to be able to stop the animation where it is and take over the scrolling manually. I'm thinking there should be a way to use the animation's start time and the current graphics time to determine how long the animation has been running to determine where the ContentOffset would have been at that time, then jumping back there. That sounds very hacky to me though, less than ideal.

Note: I know I could just have used UIView.Animate with UIViewAnimationOptions.Autoreverse, I just didn't know about that at the time. I've also been able to implement the behaviour I want using a timer to set the ContentOffset periodically. It's CPU bound though, so it's not very smooth.

在从滚动视图的图层中删除所有动画之前,请从其presentationLayer读取bounds.origin并将其contentOffset设置为该值。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM