2016-11-16 2 views
0

私は以下のFLowLayoutをObjective CからSwift 3に変換しようとしています。残念ながら、私はnullエラーを受け取ります。誰もが既にSwift 3に類似したコードを実装していますか?ここでSpringy Collection View LibrarySpringyCollectionViewをSwiftに変換する

私がこれまでに得たものである:

override func prepare() { 
    super.prepare() 


    // Need to overflow our actual visible rect slightly to avoid flickering. 
    let visibleRect = self.collectionView!.bounds.insetBy(dx: -100, dy: -100) 
    let itemsInVisibleRectArray: NSArray = super.layoutAttributesForElements(in: visibleRect)! as NSArray 
    let itemsIndexPathsInVisibleRectSet: NSSet = NSSet(array: itemsInVisibleRectArray.value(forKey: "indexPath") as! [AnyObject]) 

    // Step 1: Remove any behaviours that are no longer visible. 
    let noLongerVisibleBehaviours = (self.dynamicAnimator.behaviors as NSArray).filtered(using: NSPredicate(block: {behaviour, bindings in 
     let currentlyVisible: Bool = itemsIndexPathsInVisibleRectSet.member((behaviour as! UIAttachmentBehavior).items.first!) != nil 
     return !currentlyVisible 
    })) 


    for (_, obj) in noLongerVisibleBehaviours.enumerated() { 
     self.dynamicAnimator.removeBehavior(obj as! UIDynamicBehavior) 
     self.visibleIndexPathsSet.remove((obj as! UIAttachmentBehavior).items.first!) 
    } 

    // Step 2: Add any newly visible behaviours. 
    // A "newly visible" item is one that is in the itemsInVisibleRect(Set|Array) but not in the visibleIndexPathsSet 
    let newlyVisibleItems = itemsInVisibleRectArray.filtered(using: NSPredicate(block: {item, bindings in 
     let currentlyVisible: Bool = self.visibleIndexPathsSet.member(item!) != nil 
     return !currentlyVisible 
    })) 

    let touchLocation: CGPoint = self.collectionView!.panGestureRecognizer.location(in: self.collectionView) 

    for (_, item) in newlyVisibleItems.enumerated() { 
     let springBehaviour: UIAttachmentBehavior = UIAttachmentBehavior(item: item as! UIDynamicItem, attachedToAnchor: (item as AnyObject).center) 

     springBehaviour.length = CGFloat(kLength) 
     springBehaviour.damping = CGFloat(kDamping) 
     springBehaviour.frequency = CGFloat(kFrequence) 

     let zeropoint = CGPoint(x: 0,y :0) 

     // If our touchLocation is not (0,0), we'll need to adjust our item's center "in flight" 
     if (!zeropoint.equalTo(touchLocation)) { 
      let yDistanceFromTouch = fabsf(Float(touchLocation.y - springBehaviour.anchorPoint.y)) 
      let xDistanceFromTouch = fabsf(Float(touchLocation.x - springBehaviour.anchorPoint.x)) 
      let scrollResistance = (yDistanceFromTouch + xDistanceFromTouch)/Float(kResistence) 

      let item = springBehaviour.items.first as! UICollectionViewLayoutAttributes 
      var center = item.center 

      if self.latestDelta < 0 { 
       center.x += max(self.latestDelta, self.latestDelta * CGFloat(scrollResistance)) 
      } else { 
       center.x += min(self.latestDelta, self.latestDelta * CGFloat(scrollResistance)) 
      } 

      item.center = center 
     } 

     self.dynamicAnimator.addBehavior(springBehaviour) 
     self.visibleIndexPathsSet.add(item) 
    } 
} 

私はここで最初のエラーを取得:

enter image description here

答えて

0

ネイティブの迅速な型を使用する方が良いでしょう。ような何か:NSArrayNSPredicateを使用して

override func prepare() 
    { 
     super.prepare() 
     let visibleRect = CGRect(origin: self.collectionView?.bounds.origin ?? CGPoint.zero, size: self.collectionView?.frame.size ?? CGSize.zero).insetBy(dx: -100, dy: -100) 

     let itemsInVisibleRectArray = super.layoutAttributesForElements(in: visibleRect) ?? [] 
     let itemsIndexPathsInVisibleRectSet = Set(itemsInVisibleRectArray.map{ $0.indexPath }) 

     let noLongerVisibleBehaviors = self.dynamicAnimator.behaviors.filter 
     { behavior in 
      guard let behavior = behavior as? UIAttachmentBehavior else { return false } 
      guard let attribute = behavior.items.first as? UICollectionViewLayoutAttributes else { return false } 
      let currentlyVisible = itemsIndexPathsInVisibleRectSet.contains(attribute.indexPath) 
      return !currentlyVisible 
     } 

     noLongerVisibleBehaviors.forEach 
     { behavior in 
      self.dynamicAnimator.removeBehavior(behavior) 
      guard let behavior = behavior as? UIAttachmentBehavior else { return } 
      guard let attribute = behavior.items.first as? UICollectionViewLayoutAttributes else { return } 
      self.visibleIndexPathsSet.remove(attribute.indexPath) 
     } 

     let newlyVisibleItems = itemsInVisibleRectArray.filter 
     { item in 
      let currentlyVisible = self.visibleIndexPathsSet.contains(item.indexPath) 
      return !currentlyVisible 
     } 
     let touchLocation = self.collectionView?.panGestureRecognizer.location(in: self.collectionView) 

     newlyVisibleItems.forEach 
     { item in 
      var center = item.center 
      let springBehavior = UIAttachmentBehavior(item: item, attachedToAnchor: center) 

      springBehavior.length = 0.0 
      springBehavior.damping = 0.8 
      springBehavior.frequency = 1.0 

      if CGPoint.zero != touchLocation 
      { 
       let yDistanceFromTouch = fabs(touchLocation?.y ?? 0 - springBehavior.anchorPoint.y) 
       let xDistanceFromTouch = fabs(touchLocation?.x ?? 0 - springBehavior.anchorPoint.x) 
       let scrollResistance = (yDistanceFromTouch + xDistanceFromTouch)/1500.0 

       if self.latestDelta < 0.0 
       { 
        center.y += max(self.latestDelta, self.latestDelta * scrollResistance) 
       } 
       else 
       { 
        center.y += min(self.latestDelta, self.latestDelta * scrollResistance) 
       } 
       item.center = center 
      } 
      self.dynamicAnimator.addBehavior(springBehavior) 
      self.visibleIndexPathsSet.insert(item.indexPath) 
     } 
    } 

は静的型付けと非常にswiftyをエラーをランタイムとすべての周りではないしやすいされていません。

私はスプリング効果が働きます。あなたは、コードhere.のすべてを見ることができます

enter image description here

は、おそらくそれはあなたが期待する以上に微妙です。

+0

申し訳ありませんが、もうエラーはありません。しかし、私のCollectionviewではアニメーションは発生しませんが、通常のフローレイアウトのようです。 –

+0

それは私のために働く。私は使用したすべてのコードへのリンクで回答を更新しました。 – beyowulf

+0

ありがとうございました。あなたのコードをコピーし、今は魅力のように動作します! –

関連する問題