Ambiguous use of the "index" - ios 9 Swift 2.0

I wrote an ios application using Swift 2.0 on xcode 7.0. Before upgrading to the latest version of xCode 7.1, the same exact code worked fine

After the update, I received this error:

Ambiguous use of the "index"

in these lines:

override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> (UICollectionViewLayoutAttributes!) { return self.itemAttributes[indexPath.section][indexPath.row] as! UICollectionViewLayoutAttributes } 

this is the full class:

 class CustomCollectionViewLayout: UICollectionViewLayout { var numberOfColumns = 7 // the number of columns var itemAttributes : NSMutableArray! var itemsSize : NSMutableArray! var contentSize : CGSize! func setColumnNumber(columnNum: Int) { numberOfColumns = columnNum } override func prepareLayout() { if self.collectionView?.numberOfSections() == 0 { return } if (self.itemAttributes != nil && self.itemAttributes.count > 0) { for section in 0..<self.collectionView!.numberOfSections() { let numberOfItems : Int = self.collectionView!.numberOfItemsInSection(section) for index in 0..<numberOfItems { if section != 0 && index != 0 { continue } let attributes : UICollectionViewLayoutAttributes = self.layoutAttributesForItemAtIndexPath(NSIndexPath(forItem: index, inSection: section)) if section == 0 { var frame = attributes.frame frame.origin.y = self.collectionView!.contentOffset.y attributes.frame = frame } if index == 0 { var frame = attributes.frame frame.origin.x = self.collectionView!.contentOffset.x attributes.frame = frame } } } return } if (self.itemsSize == nil || self.itemsSize.count != numberOfColumns) { self.calculateItemsSize() } var column = 0 var xOffset : CGFloat = 0 var yOffset : CGFloat = 0 var contentWidth : CGFloat = 0 var contentHeight : CGFloat = 0 for section in 0..<self.collectionView!.numberOfSections() { let sectionAttributes = NSMutableArray() for index in 0..<numberOfColumns { let itemSize = self.itemsSize[index].CGSizeValue() let indexPath = NSIndexPath(forItem: index, inSection: section) let attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath) attributes.frame = CGRectIntegral(CGRectMake(xOffset, yOffset, itemSize.width, itemSize.height)) if section == 0 && index == 0 { attributes.zIndex = 1024; } else if section == 0 || index == 0 { attributes.zIndex = 1023 } if section == 0 { var frame = attributes.frame frame.origin.y = self.collectionView!.contentOffset.y attributes.frame = frame } if index == 0 { var frame = attributes.frame frame.origin.x = self.collectionView!.contentOffset.x attributes.frame = frame } sectionAttributes.addObject(attributes) xOffset += itemSize.width column++ if column == numberOfColumns { if xOffset > contentWidth { contentWidth = xOffset } column = 0 xOffset = 0 yOffset += itemSize.height } } if (self.itemAttributes == nil) { self.itemAttributes = NSMutableArray(capacity: self.collectionView!.numberOfSections()) } self.itemAttributes .addObject(sectionAttributes) } let attributes : UICollectionViewLayoutAttributes = self.itemAttributes.lastObject?.lastObject as! UICollectionViewLayoutAttributes contentHeight = attributes.frame.origin.y + attributes.frame.size.height if( contentWidth == 0 || contentHeight == 0){return;} self.contentSize = CGSizeMake(contentWidth, contentHeight) } override func collectionViewContentSize() -> CGSize { if( self.contentSize != nil){ return self.contentSize }else { return CGSizeMake(0, 0) } } override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> (UICollectionViewLayoutAttributes!) { return self.itemAttributes[indexPath.section][indexPath.row] as! UICollectionViewLayoutAttributes } override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? { var attributes = [UICollectionViewLayoutAttributes]() if self.itemAttributes != nil { for section in self.itemAttributes { let filteredArray = section.filteredArrayUsingPredicate( NSPredicate(block: { (evaluatedObject, bindings) -> Bool in return CGRectIntersectsRect(rect, evaluatedObject.frame) }) ) as! [UICollectionViewLayoutAttributes] attributes.appendContentsOf(filteredArray) } } return attributes } override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool { return true } func sizeForItemWithColumnIndex(columnIndex: Int) -> CGSize { let text : String = "25.10.15" let size : CGSize = (text as NSString).sizeWithAttributes([NSFontAttributeName: UIFont.systemFontOfSize(17.0)]) let width : CGFloat = size.width + 25 return CGSizeMake(width, 30) } func calculateItemsSize() { self.itemsSize = NSMutableArray(capacity: numberOfColumns) for index in 0..<numberOfColumns { self.itemsSize.addObject(NSValue(CGSize: self.sizeForItemWithColumnIndex(index))) } } } 

Original library

+6
source share
2 answers

The compiler does not know that self.itemAttributes[indexPath.section] returned, since it is defined as NSMutableArray . Instead, you should define itemAttributes as an array of the UICollectionViewLayoutAttributes array, which looks like you have one. Therefore, itemAttributes: [[UICollectionViewLayoutAttributes]] should take care of this warning and be the preferred way of writing this word in Swift.

Edit: You must also override sectionAttributes as [UICollectionViewLayoutAttributes] . So, now the compiler can completely specify the type of the returned object for the subscription.

As for the change in the recent release, I'm not sure I see anything about this specifically in the release notes.

+7
source

By sending the answer "Peter Foti", I changed the code to

 let sectionAttributes = self.itemAttributes [indexPath.section] as! [UICollectionViewLayoutAttributes] return sectionAttributes[indexPath.row] as UICollectionViewLayoutAttributes 

Instead of a line with the "Ambiguous use of" index "error

 return self.itemAttributes[indexPath.section][indexPath.row] as! UICollectionViewLayoutAttributes 
+7
source

All Articles