#nspredicate #swift3 #uicollectionviewlayout
#nspredicate #swift3 #uicollectionviewlayout
Вопрос:
Я пытаюсь изменить это:
return [self.allAttributes filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(UICollectionViewLayoutAttributes *layoutAttributes, NSDictionary *bindings) {
return CGRectIntersectsRect(rect, layoutAttributes.frame);
}]];
во что-то, что работает в swift3. До сих пор я пробовал это:
return self.allAttributes?.filtered(using: NSPredicate(block: { (layoutAttributes, bindings) -> Bool in
return rect.intersects(layoutAttributes.frame)
})) as! [UICollectionViewLayoutAttributes]?
но, конечно, я получаю Value of type 'Any?' has no member 'frame'
Я искал весь день, но не могу найти решение.
Ответ №1:
Предполагая, что ваш allAttributes
объявлен как NSArray
.
Тогда в любом случае вам нужно какое-то приведение, чтобы вы могли написать что-то вроде этого:
return self.allAttributes?.filtered(using: NSPredicate(block: { (layoutAttributes, bindings) -> Bool in
guard let layoutAttributes = layoutAttributes as? UICollectionViewLayoutAttributes else {
print("some thing is wrong...")
return false
}
return rect.intersects(layoutAttributes.frame)
})) as! [UICollectionViewLayoutAttributes]?
Но если вы содержите только UICollectionViewLayoutAttributes
, почему бы вам не объявить его как Swift Array, [UICollectionViewLayoutAttributes]
?
var allAttributes: [UICollectionViewLayoutAttributes] = []
//...
return allAttributes.filter {rect.intersects($0.frame)}
Вам могут потребоваться некоторые исправления в соответствии с этим изменением, но обычно такие исправления делают ваш код более простым и читаемым.