PageControl 触发的 IOs CollectionView 的 SetContentOffset 自定义动画不流畅
Custom animation on SetContentOffset for IOs CollectionView triggered by PageControl is not smooth
我有一个 Xamarin.IOs 项目。我正在使用启用了分页的 UICollectionView。然后是与 UICollectionView 同步的 UIPageControl。
需要两个功能,
滑动UICollectionView时,CollectionView的当前页面会发生变化,UIPageControl的当前指示器也会同步变化
实施:
在 UICollectionViewSource 中,
public override void DecelerationEnded(UIScrollView scrollView)
{
Index = (int)(scrollView.ContentOffset.X / scrollView.Frame.Width);
PageControl.CurrentPage = Index;
CardSwiped?.Invoke(this, new CustomEventArgs(Index));
}
在相关ViewController,
private void SomeMethod()
{
CollectionSource.CardSwiped += OnCardSwiped;
}
private void OnCardSwiped(object sender, CustomEventArgs args)
{
// Perform some action
}
工作正常!
点击UIPageControl时,CollectionView当前页面会随着点击而变化,UIPageControl的当前指示器也会同步变化。
实施:
在相关ViewController,
private void SomeMethod()
{
PageControl.PrimaryActionTriggered += OnPageControlTapped;
}
private void OnPageControlTapped(object sender, EventArgs args)
{
// Some action
var pageControlIndex = CardPageControl.CurrentPage;
var sourceIndex = CollectionSource.Index;
var distanceToScroll = CardCollectionView.Frame.Width * (pageControlIndex - sourceIndex);
UIView.Animate(0.5, 0, UIViewAnimationOptions.TransitionNone,
() =>
{
CollectionView.SetContentOffset(
new CGPoint(CollectionView.ContentOffset.X + distanceToScroll, CollectionView.ContentOffset.Y),
false);
},
() =>
{
CollectionSource.DecelerationEnded(CollectionView);
});
}
我无法在动画为真时调用 SetContentOffset,
CollectionView.SetContentOffset(new CGPoint(CollectionView.ContentOffset.X + y, CollectionView.ContentOffset.Y), true);
因为我需要在 SetContentOffset 方法定位页面后调用 CollectionSource.DecelerationEnded(CollectionView);
。
问题是,当我使用这个自定义动画时,CollectionView 的动画效果不正确,
我该如何克服这个问题?
启用 Paging 时,UICollectionView 如何使用自定义动画滚动 SetContentOffset 似乎存在一些问题。
当以整页宽度(CardCollectionView.Frame.Width
)为滚动距离时,
var distanceToScroll = CardCollectionView.Frame.Width * (pageControlIndex - sourceIndex);
并在 SetContentOffset 中使用,
CollectionView.SetContentOffset(
new CGPoint(CollectionView.ContentOffset.X + distanceToScroll, CollectionView.ContentOffset.Y),
false);
那么它就不会像使用自定义动画那样设置动画。
解决方案:
您不应为 整页宽度 滚动距离自定义动画,而应将滚动距离减少 1 像素 (选择 1 个像素以使其不那么引人注目,任何其他数量也可以) 来自 整页宽度 。也就是说,
var distanceToScroll = (CardCollectionView.Frame.Width - 1) * (pageControlIndex - sourceIndex);
CardCollectionView.Frame.Width - 1
中的 -1 就是所谓的解决方法。
然后你必须在动画之后解决这个减少问题。即在上面的UIView.Animate代码中,回调函数要多出一行,
CardCollectionView.SetContentOffset(
new CGPoint(CardCollectionView.ContentOffset.X + (pageControlIndex - sourceIndex), CardCollectionView.ContentOffset.Y),
false);
那么 UIView.Animate 看起来像,
UIView.Animate(0.5, 0, UIViewAnimationOptions.TransitionNone,
() =>
{
CollectionView.SetContentOffset(
new CGPoint(CollectionView.ContentOffset.X + distanceToScroll, CollectionView.ContentOffset.Y),
false);
},
() =>
{
CardCollectionView.SetContentOffset(
new CGPoint(CardCollectionView.ContentOffset.X + (pageControlIndex - sourceIndex), CardCollectionView.ContentOffset.Y),
false);
CollectionSource.DecelerationEnded(CollectionView);
});
现在自定义动画会非常流畅
我有一个 Xamarin.IOs 项目。我正在使用启用了分页的 UICollectionView。然后是与 UICollectionView 同步的 UIPageControl。
需要两个功能,
滑动UICollectionView时,CollectionView的当前页面会发生变化,UIPageControl的当前指示器也会同步变化
实施:
在 UICollectionViewSource 中,
public override void DecelerationEnded(UIScrollView scrollView) { Index = (int)(scrollView.ContentOffset.X / scrollView.Frame.Width); PageControl.CurrentPage = Index; CardSwiped?.Invoke(this, new CustomEventArgs(Index)); }
在相关ViewController,
private void SomeMethod() { CollectionSource.CardSwiped += OnCardSwiped; } private void OnCardSwiped(object sender, CustomEventArgs args) { // Perform some action }
工作正常!
点击UIPageControl时,CollectionView当前页面会随着点击而变化,UIPageControl的当前指示器也会同步变化。
实施:
在相关ViewController,
private void SomeMethod() { PageControl.PrimaryActionTriggered += OnPageControlTapped; } private void OnPageControlTapped(object sender, EventArgs args) { // Some action var pageControlIndex = CardPageControl.CurrentPage; var sourceIndex = CollectionSource.Index; var distanceToScroll = CardCollectionView.Frame.Width * (pageControlIndex - sourceIndex); UIView.Animate(0.5, 0, UIViewAnimationOptions.TransitionNone, () => { CollectionView.SetContentOffset( new CGPoint(CollectionView.ContentOffset.X + distanceToScroll, CollectionView.ContentOffset.Y), false); }, () => { CollectionSource.DecelerationEnded(CollectionView); }); }
我无法在动画为真时调用 SetContentOffset,
CollectionView.SetContentOffset(new CGPoint(CollectionView.ContentOffset.X + y, CollectionView.ContentOffset.Y), true);
因为我需要在 SetContentOffset 方法定位页面后调用
CollectionSource.DecelerationEnded(CollectionView);
。问题是,当我使用这个自定义动画时,CollectionView 的动画效果不正确,
我该如何克服这个问题?
启用 Paging 时,UICollectionView 如何使用自定义动画滚动 SetContentOffset 似乎存在一些问题。
当以整页宽度(CardCollectionView.Frame.Width
)为滚动距离时,
var distanceToScroll = CardCollectionView.Frame.Width * (pageControlIndex - sourceIndex);
并在 SetContentOffset 中使用,
CollectionView.SetContentOffset(
new CGPoint(CollectionView.ContentOffset.X + distanceToScroll, CollectionView.ContentOffset.Y),
false);
那么它就不会像使用自定义动画那样设置动画。
解决方案:
您不应为 整页宽度 滚动距离自定义动画,而应将滚动距离减少 1 像素 (选择 1 个像素以使其不那么引人注目,任何其他数量也可以) 来自 整页宽度 。也就是说,
var distanceToScroll = (CardCollectionView.Frame.Width - 1) * (pageControlIndex - sourceIndex);
CardCollectionView.Frame.Width - 1
中的 -1 就是所谓的解决方法。
然后你必须在动画之后解决这个减少问题。即在上面的UIView.Animate代码中,回调函数要多出一行,
CardCollectionView.SetContentOffset(
new CGPoint(CardCollectionView.ContentOffset.X + (pageControlIndex - sourceIndex), CardCollectionView.ContentOffset.Y),
false);
那么 UIView.Animate 看起来像,
UIView.Animate(0.5, 0, UIViewAnimationOptions.TransitionNone,
() =>
{
CollectionView.SetContentOffset(
new CGPoint(CollectionView.ContentOffset.X + distanceToScroll, CollectionView.ContentOffset.Y),
false);
},
() =>
{
CardCollectionView.SetContentOffset(
new CGPoint(CardCollectionView.ContentOffset.X + (pageControlIndex - sourceIndex), CardCollectionView.ContentOffset.Y),
false);
CollectionSource.DecelerationEnded(CollectionView);
});
现在自定义动画会非常流畅