2016-06-23 46 views
8

ho costruire un UICollectionview circolare seguendo This guida, Tutto sta funzionando come previsto, ma non voglio che gli elementi di ruotare intorno al proprio angolo/anchorUICollectionview circolare, come mantenere tutti gli angoli delle cellule 0 °

Il fila superiore è come il mio CollectionView circolare sta lavorando in questo momento, il disegno in basso è come vorrei mio CollectionView:

Design

sto usando seguente codice attributo la layout:

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 
} 
} 

con la seguente classe di layout:

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 
} 
} 

Ho provato molte cose ma non era in grado di cambiare la rotazione cella

+0

hai provato cambiando l'angolo in CellForItemAtindexPath piuttosto che a la youtAttributes? –

+0

Vorrei raccomandare di ignorare la trasformazione e usare solo l'angolo per calcolare 'center', cioè usando le funzioni' sin' e 'cos'. – Sulthan

risposta

2

Ho risolto questo problema Rotateing vista di cellula di un angolo negativo :

codice qui sotto:

 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

Grazie mille, cambiato viewRoot alla mia UILabel e Imageview e funziona perfettamente! –