雖然this answer一直對我有很大的幫助的開始,有一個明顯的閃爍,當你在一個小的距離刷快。在設備上重現它要容易得多。
我發現這總是發生在collectionView.contentOffset.x - proposedContentOffset.x
和velocity.x
有不同的唱歌。
我的解決方案是確保proposedContentOffset
大於contentOffset.x
如果速度是正值,如果是負值,則更少。這是在C#中,但應該是相當簡單的翻譯到目標C:
public override PointF TargetContentOffset (PointF proposedContentOffset, PointF scrollingVelocity)
{
/* Determine closest edge */
float offSetAdjustment = float.MaxValue;
float horizontalCenter = (float) (proposedContentOffset.X + (this.CollectionView.Bounds.Size.Width/2.0));
RectangleF targetRect = new RectangleF (proposedContentOffset.X, 0.0f, this.CollectionView.Bounds.Size.Width, this.CollectionView.Bounds.Size.Height);
var array = base.LayoutAttributesForElementsInRect (targetRect);
foreach (var layoutAttributes in array) {
float itemHorizontalCenter = layoutAttributes.Center.X;
if (Math.Abs (itemHorizontalCenter - horizontalCenter) < Math.Abs (offSetAdjustment)) {
offSetAdjustment = itemHorizontalCenter - horizontalCenter;
}
}
float nextOffset = proposedContentOffset.X + offSetAdjustment;
/*
* ... unless we end up having positive speed
* while moving left or negative speed while moving right.
* This will cause flicker so we resort to finding next page
* in the direction of velocity and use it.
*/
do {
proposedContentOffset.X = nextOffset;
float deltaX = proposedContentOffset.X - CollectionView.ContentOffset.X;
float velX = scrollingVelocity.X;
// If their signs are same, or if either is zero, go ahead
if (Math.Sign (deltaX) * Math.Sign (velX) != -1)
break;
// Otherwise, look for the closest page in the right direction
nextOffset += Math.Sign (scrollingVelocity.X) * SnapStep;
} while (IsValidOffset (nextOffset));
return proposedContentOffset;
}
bool IsValidOffset (float offset)
{
return (offset >= MinContentOffset && offset <= MaxContentOffset);
}
該代碼使用MinContentOffset
,MaxContentOffset
和SnapStep
這應該是平凡的你來定義。在我的情況下,他們竟然是
float MinContentOffset {
get { return -CollectionView.ContentInset.Left; }
}
float MaxContentOffset {
get { return MinContentOffset + CollectionView.ContentSize.Width - ItemSize.Width; }
}
float SnapStep {
get { return ItemSize.Width + MinimumLineSpacing; }
}
感謝您的問題和答案。完全幫助我,開始喜歡UICollectionViews! – nicktones
正確使用它確實很強大。您是否觀看過WWDC 2012的Collection View會話?他們真的值得一看。一些不可思議的東西。 – Fogmeister
我有很棒的東西。您的解決方案效果很好,除了第一個和最後一個單元格,它們可以在屏幕上「粘貼」一半。任何想法如何解決?我有一個水平集合視圖,很像App Store中的應用程序列表。 – nicktones