2016-06-23 20 views
8

tôi xây dựng một UICollectionview tròn bằng cách làm theo hướng dẫn This, Tất cả mọi thứ đang làm việc như mong đợi nhưng tôi không muốn các mục để xoay xung quanh góc riêng của mình/neoThông tư UICollectionview, làm thế nào để giữ cho tất cả các tế bào góc 0 °

Các hàng đầu tiên là cách collectionview tròn của tôi đang làm việc tại thời điểm này, các bản vẽ chốt là làm thế nào tôi muốn collectionview tôi:

Design

tôi đang sử dụng mã sau đây thuộc tính bố trí:

class CircularCollectionViewLayoutAttributes: UICollectionViewLayoutAttributes { 

var anchorPoint = CGPoint(x: 0.3, y: 0.5) 

var angle: CGFloat = 0 { 
    didSet { 
     zIndex = Int(angle*1000000) 
     transform = CGAffineTransformMakeRotation(angle) 
    } 
} 

override func copyWithZone(zone: NSZone) -> AnyObject { 
    let copiedAttributes: CircularCollectionViewLayoutAttributes = super.copyWithZone(zone) as! CircularCollectionViewLayoutAttributes 
    copiedAttributes.anchorPoint = self.anchorPoint 
    copiedAttributes.angle = self.angle 
    return copiedAttributes 
} 
} 

với lớp bố trí như sau:

class CircularCollectionViewLayout: UICollectionViewLayout { 
let itemSize = CGSize(width: 60, height: 110) 
var angleAtExtreme: CGFloat { 

    return collectionView!.numberOfItemsInSection(0) > 0 ? -CGFloat(collectionView!.numberOfItemsInSection(0)-1)*anglePerItem : 0 
} 

var angle: CGFloat { 
    return angleAtExtreme*collectionView!.contentOffset.x/(collectionViewContentSize().width - CGRectGetWidth(collectionView!.bounds)) 
} 

var radius: CGFloat = 400 { 
    didSet { 
     invalidateLayout() 
    } 
} 

var anglePerItem: CGFloat { 
    return 0.18 
} 

var attributesList = [CircularCollectionViewLayoutAttributes]() 

override func collectionViewContentSize() -> CGSize { 
    return CGSize(width: CGFloat(collectionView!.numberOfItemsInSection(0))*itemSize.width, 
        height: CGRectGetHeight(collectionView!.bounds)) 
} 

override class func layoutAttributesClass() -> AnyClass { 
    return CircularCollectionViewLayoutAttributes.self 
} 

override func prepareLayout() { 
    super.prepareLayout() 
    let centerX = collectionView!.contentOffset.x + (CGRectGetWidth(collectionView!.bounds)/2.0) 
    let anchorPointY = ((itemSize.height/2.0) + radius)/itemSize.height 

    let theta = atan2(CGRectGetWidth(collectionView!.bounds)/2.0, radius + (itemSize.height/2.0) - (CGRectGetHeight(collectionView!.bounds)/2.0)) //1 
    //let theta:CGFloat = 1.0 


    var startIndex = 0 
    var endIndex = collectionView!.numberOfItemsInSection(0) - 1 

    if (angle < -theta) { 
     startIndex = Int(floor((-theta - angle)/anglePerItem)) 
    } 

    endIndex = min(endIndex, Int(ceil((theta - angle)/anglePerItem))) 

    if (endIndex < startIndex) { 
     endIndex = 0 
     startIndex = 0 
    } 
    attributesList = (startIndex...endIndex).map { (i) -> CircularCollectionViewLayoutAttributes in 
     let attributes = CircularCollectionViewLayoutAttributes(forCellWithIndexPath: NSIndexPath(forItem: i, inSection: 0)) 
     attributes.size = self.itemSize 
     attributes.center = CGPoint(x: centerX, y: CGRectGetMidY(self.collectionView!.bounds)) 
     attributes.angle = self.angle + (self.anglePerItem*CGFloat(i)) 
     attributes.anchorPoint = CGPoint(x: 0.5, y: anchorPointY) 
     return attributes 
    } 
} 

override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? { 
    return attributesList 
} 

override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) 
    -> (UICollectionViewLayoutAttributes!) { 
     return attributesList[indexPath.row] 
} 

override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool { 
    return true 
} 


override func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint { 
    var finalContentOffset = proposedContentOffset 
    let factor = -angleAtExtreme/(collectionViewContentSize().width - CGRectGetWidth(collectionView!.bounds)) 
    let proposedAngle = proposedContentOffset.x*factor 
    let ratio = proposedAngle/anglePerItem 
    var multiplier: CGFloat 
    if (velocity.x > 0) { 
     multiplier = ceil(ratio) 
    } else if (velocity.x < 0) { 
     multiplier = floor(ratio) 
    } else { 
     multiplier = round(ratio) 
    } 
    finalContentOffset.x = multiplier*anglePerItem/factor 
    return finalContentOffset 
} 
} 

tôi đã cố gắng rất nhiều điều nhưng tôi đã không thể thay đổi luân chuyển tế bào

+0

bạn hãy thử thay đổi góc trong CellForItemAtindexPath chứ không phải ở La youtAttributes? –

+0

Tôi khuyên bạn nên bỏ qua biến đổi và chỉ sử dụng góc để tính 'trung tâm', tức là, sử dụng các hàm' sin' và 'cos'. – Sulthan

Trả lời

2

Tôi đã giải quyết vấn đề này bằng rotateing quan điểm của tế bào bằng góc tiêu cực :

Mã dưới đây:

 override func applyLayoutAttributes(layoutAttributes: UICollectionViewLayoutAttributes!) { 
super.applyLayoutAttributes(layoutAttributes) 
let circularlayoutAttributes = layoutAttributes as! CircularCollectionViewLayoutAttributes 
self.layer.anchorPoint = circularlayoutAttributes.anchorPoint 

viewRoot.transform = CGAffineTransformMakeRotation(-circularlayoutAttributes.angle) 

self.center.y += (circularlayoutAttributes.anchorPoint.y - 0.5) * CGRectGetHeight(self.bounds) 
} 
+0

Cảm ơn bạn rất nhiều, đã thay đổi viewRoot thành UILabel và Imageview của tôi và làm việc hoàn hảo! –

Các vấn đề liên quan