Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XCode 7: Copy Layoutattributes

I'm getting the warning "This is likely occurring because the flow layout subclass MyApp.MenuFlowLayout is modifying attributes returned by UICollectionViewFlowLayout without copying them". How can I copy this in Swift?

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

    if let array = super.layoutAttributesForElementsInRect(rect) as [UICollectionViewLayoutAttributes]? {

        var visibleRect = CGRectZero
        visibleRect.origin = (self.collectionView?.contentOffset)!
        visibleRect.size = (self.collectionView?.bounds.size)!


        let activeDisatance : CGFloat = visibleRect.size.width / 2
        let zoomFactor : CGFloat = 0.15

        for attributes in array{
            if CGRectIntersectsRect(attributes.frame, visibleRect){
                let distance  = CGRectGetMidX(visibleRect) - attributes.center.x
                let normalizedDistance = distance / activeDisatance
                if abs(distance) < activeDisatance{
                    let zoom = 1 + zoomFactor * (1 - abs(normalizedDistance))
                    attributes.transform3D = CATransform3DMakeScale(zoom, zoom, 1.0)
                    attributes.zIndex = 1
                }
            }
        }
        return array
    }
    return super.layoutAttributesForElementsInRect(rect)
}
like image 557
netshark1000 Avatar asked Dec 25 '22 14:12

netshark1000


1 Answers

Collections in Swift are value types, that's the reason why they don't have a copy() method. So when you are calling

array = super.layoutAttributesForElementsInRect(rect) as [UICollectionViewLayoutAttributes]?

it already creates a copy of the super layout attributes array and stores it in array

The problem is not that the array has not been copied, the problem is, that you are changing the UICollectionViewLayoutAttributes inside the array without copying them first.

To avoid this error message you can do something like this:

override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    let attributes = super.layoutAttributesForElementsInRect(rect)
    var attributesCopy = [UICollectionViewLayoutAttributes]()
    for itemAttributes in attributes! {
        let itemAttributesCopy = itemAttributes.copy() as! UICollectionViewLayoutAttributes
        // add the changes to the itemAttributesCopy                       
        attributesCopy.append(itemAttributesCopy)
    }

    return attributesCopy
}
like image 138
joern Avatar answered Jan 13 '23 04:01

joern