@@ -146,67 +146,46 @@ import UIKit
146146 internal var cachedContentSize : CGFloat = 0
147147
148148 /// :nodoc:
149- fileprivate func itemSize( forItemAt indexPath: IndexPath ) -> CGFloat {
149+ fileprivate func itemSize( forItemAt indexPath: IndexPath ) -> ( value : CGFloat , isDynamic : Bool ) {
150150 guard let collectionView = collectionView,
151151 let delegate = collectionView. delegate as? CollectionViewDelegateSlantedLayout else {
152- return max ( itemSize, 0 )
152+ return ( max ( itemSize, 0 ) , false )
153153 }
154154
155155 let size = delegate. collectionView ? ( collectionView, layout: self , sizeForItemAt: indexPath)
156- return max ( size ?? itemSize, 0 )
156+ return ( max ( size ?? itemSize, 0 ) , size != nil )
157157 }
158158
159159 /// :nodoc:
160- fileprivate func maskForItemAtIndexPath( _ indexPath: IndexPath ) -> CAShapeLayer {
161- let size = itemSize ( forItemAt: indexPath)
160+ fileprivate func maskForItemAtIndexPath( _ indexPath: IndexPath ,
161+ size: CGFloat ,
162+ isDynamicSize: Bool ,
163+ staticMasks: CollectionViewSlantedMasks ) -> CAShapeLayer {
162164
163- let isFirstCellExcluded = indexPath. row == 0 && self . isFirstCellExcluded
164- let isLastCellExcluded = indexPath. row == numberOfItems - 1 && self . isLastCellExcluded
165+ let masks = isDynamicSize ? calculatedMasks ( itemSize: size) : CollectionViewSlantedMasks ( masks: staticMasks)
165166
166- let firstControlPoint = isFirstCellExcluded ? 0 : CGFloat ( slantingSize)
167- let secondControlPoint = isLastCellExcluded ? size : size - CGFloat( slantingSize)
168-
169- var pathPoints = [ CGPoint] ( )
170-
171- if scrollDirection. isVertical {
172- switch self . slantingDirection {
173- case . downward:
174- pathPoints = [ CGPoint ( x: 0 , y: 0 ) ,
175- CGPoint ( x: width, y: firstControlPoint) ,
176- CGPoint ( x: width, y: size) ,
177- CGPoint ( x: 0 , y: secondControlPoint) ]
178- default :
179- pathPoints = [ CGPoint ( x: 0 , y: firstControlPoint) ,
180- CGPoint ( x: width, y: 0 ) ,
181- CGPoint ( x: width, y: secondControlPoint) ,
182- CGPoint ( x: 0 , y: size) ]
183- }
184- } else {
185- switch self . slantingDirection {
186- case . upward:
187- pathPoints = [ CGPoint ( x: firstControlPoint, y: 0 ) ,
188- CGPoint ( x: size, y: 0 ) ,
189- CGPoint ( x: secondControlPoint, y: height) ,
190- CGPoint ( x: 0 , y: height) ]
191- default :
192- pathPoints = [ CGPoint ( x: 0 , y: 0 ) ,
193- CGPoint ( x: secondControlPoint, y: 0 ) ,
194- CGPoint ( x: size, y: height) ,
195- CGPoint ( x: firstControlPoint, y: height) ]
196- }
167+ // isFirstCell && isFirstCellExcluded
168+ if indexPath. row == 0 && isFirstCellExcluded {
169+ return masks. startingMask
197170 }
198171
199- let bezierPath = UIBezierPath ( )
200- bezierPath. move ( to: pathPoints [ 0 ] )
201- bezierPath. addLine ( to: pathPoints [ 1 ] )
202- bezierPath. addLine ( to: pathPoints [ 2 ] )
203- bezierPath. addLine ( to: pathPoints [ 3 ] )
204- bezierPath. close ( )
172+ // isLastCell && isLastCellExcluded
173+ if ( indexPath. row == numberOfItems - 1 ) && isLastCellExcluded {
174+ return masks. endingMask
175+ }
205176
206- let slantedLayerMask = CAShapeLayer ( )
207- slantedLayerMask . path = bezierPath . cgPath
177+ return masks . defaultMask
178+ }
208179
209- return slantedLayerMask
180+ /// :nodoc:
181+ fileprivate func calculatedMasks( itemSize: CGFloat ) -> CollectionViewSlantedMasks {
182+ let size = CGSize ( width: scrollDirection. isVertical ? width : itemSize,
183+ height: scrollDirection. isVertical ? itemSize : height)
184+
185+ return CollectionViewSlantedMasks ( size: size,
186+ slantingSize: CGFloat ( slantingSize) ,
187+ scrollDirection: scrollDirection,
188+ slantingDirection: slantingDirection)
210189 }
211190
212191 /// :nodoc:
@@ -227,6 +206,7 @@ import UIKit
227206 /// :nodoc:
228207 fileprivate func invalidate( ) {
229208 invalidateCache ( )
209+ updateRotationAngle ( )
230210 invalidateLayout ( )
231211 }
232212
@@ -261,32 +241,34 @@ extension CollectionViewSlantedLayout {
261241 return
262242 }
263243
264- updateRotationAngle ( )
244+ let staticMasks = calculatedMasks ( itemSize : max ( itemSize , 0 ) )
265245
266246 var position : CGFloat = 0
267247
268248 for item in 0 ..< numberOfItems {
269249 let indexPath = IndexPath ( item: item, section: 0 )
270250 let attributes = CollectionViewSlantedLayoutAttributes ( forCellWith: indexPath)
271251 let size = itemSize ( forItemAt: indexPath)
272- let frame : CGRect
273252
253+ let frame : CGRect
274254 if scrollDirection. isVertical {
275- frame = CGRect ( x: 0 , y: position, width: width, height: size)
255+ frame = CGRect ( x: 0 , y: position, width: width, height: size. value )
276256 } else {
277- frame = CGRect ( x: position, y: 0 , width: size, height: height)
257+ frame = CGRect ( x: position, y: 0 , width: size. value , height: height)
278258 }
279259
280260 attributes. frame = frame
281261 attributes. size = frame. size
282-
283262 attributes. zIndex = zIndexOrder. isAscending ? item : ( numberOfItems - item)
263+ attributes. slantedLayerMask = maskForItemAtIndexPath ( indexPath,
264+ size: size. value,
265+ isDynamicSize: size. isDynamic,
266+ staticMasks: staticMasks)
284267
285- attributes. slantedLayerMask = self . maskForItemAtIndexPath ( indexPath)
286268 cachedAttributes. append ( attributes)
287- cachedContentSize += size
269+ cachedContentSize += size. value
288270
289- position += size + lineSpacing - CGFloat( slantingSize)
271+ position += size. value + lineSpacing - CGFloat( slantingSize)
290272 }
291273 }
292274
@@ -301,4 +283,5 @@ extension CollectionViewSlantedLayout {
301283 override open func layoutAttributesForItem( at indexPath: IndexPath ) -> CollectionViewSlantedLayoutAttributes ? {
302284 return cachedAttributes [ indexPath. item]
303285 }
286+
304287}
0 commit comments