2016-06-23 3 views
8

ich eine kreisförmige UICollectionview durch folgende This Führung bauen, Alles funktioniert wie erwartet, aber ich will nicht die Gegenstände um ihre eigenen Winkel/AnkerCircular UICollectionview, wie alle Zelle zu halten Winkel 0 °

Die drehen obere Reihe ist, wie meine Kreiskollektion ist im Moment arbeiten, die untere Zeichnung ist, wie ich meine Kollektion möchte:

Design

ich folgendes Layout Attributcode bin mit:

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

mit dem folgenden Layout-Klasse:

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

ich viele Dinge ausprobiert, aber ich war nicht in der Lage, die Zell Rotation

+0

Sie versuchen Haben Sie den Winkel in CellForItemAtindexPath Wechsel statt in La youtAttributes? –

+0

Ich würde empfehlen, die Transformation zu ignorieren und nur den Winkel zu verwenden, um 'center' zu berechnen, das heißt, mit' sin' und 'cos' Funktionen. – Sulthan

Antwort

2

ich dieses Problem gelöst, indem Rotateing die Ansicht der Zelle von negativen Winkel haben sich ändern :

-Code unten:

 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

Vielen Dank, änderte die AnsichtRoot zu meinem UILabel und Imageview und funktioniert perfekt! –