NSPredicate в Swift3

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

Вам могут потребоваться некоторые исправления в соответствии с этим изменением, но обычно такие исправления делают ваш код более простым и читаемым.