2017-03-11 25 views
1

我需要能夠應用與iOS AirBNB中的滾動效果類似的滾動效果,當您滾動UI集合視圖單元格圖像時突出顯示如何獲得與AirBNB iOS應用程序類似的UIScroll效果,如下圖所示

我無法滾動發生,一個單元格停止並被選中。

iOS AirBNB App Collection View Scroll

我迄今所做的:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 
    let itemsPerRow:CGFloat = 2.3 
    let hardCodedPadding:CGFloat = 15 
    let itemWidth = (collectionView.bounds.width/itemsPerRow) - hardCodedPadding 
    let itemHeight = collectionView.bounds.height - (2 * hardCodedPadding) 
    return CGSize(width: itemWidth, height: itemHeight) 
} 
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { 
    let indexPath = IndexPath(row: collectionView.indexPathsForVisibleItems[0].row, section: 0) 

    collectionView.scrollToItem(at: indexPath, at: UICollectionViewScrollPosition.left, animated: true) 
    (collectionView.cellForItem(at: indexPath) as! productImageCell).productImage.layer.borderWidth = 5 

} 
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { 
    let cellWidth = (collectionView.bounds.width/3) 
    return UIEdgeInsetsMake(0, 5 , 0, cellWidth/3) 
} 

回答

0

,你必須做的第一件事就是用UICollectionViewDelegateUICollectionViewDataSourceUICollectionViewDelegateFlowLayout,你也應該創建一些重要的變量

class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { 
    // Used to calculate the position after the user end dragging 
    var cellWidth: CGFloat? 

    // Used to set the layout for the collectionView 
    var layout: UICollectionViewFlowLayout? 

    // The collection view 
    var collectionView: UICollectionView? 
} 

接下來,您將創建實例化佈局和集合視圖,設置一些參數rs,將集合視圖添加到視圖並最終註冊我們的單元類。你可以在你viewDidLoad()方法來完成:

override func viewDidLoad() { 
    super.viewDidLoad() 

    // You can change the width of the cell for whatever you want 
    cellWidth = view.frame.width*0.5 

    // instantiate the layout, set it to horizontal and the minimum line spacing 
    layout = UICollectionViewFlowLayout() 
    layout?.scrollDirection = .horizontal 
    layout?.minimumLineSpacing = 0 // You can also set to whatever you want 

    let cv = UICollectionView(frame: self.view.frame, collectionViewLayout: layout!) 
    cv.backgroundColor = .green 
    cv.delegate = self 
    cv.dataSource = self 
    collectionView = cv 
    collectionView?.allowsSelection = true 

    guard let collectionView = collectionView else { 
     return 
    } 

    // Add to subview 
    view.addSubview(collectionView) 

    // Set auto layout constraints 
    collectionView.translatesAutoresizingMaskIntoConstraints = false 
    collectionView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true 
    collectionView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true 
    collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true 
    collectionView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true 

    // Register cell class 
    collectionView.register(MyCollectionViewCell.self, forCellWithReuseIdentifier: "cell") 

} 

的最後一件事你ViewController要做的就是選擇用戶拖動結束後正確的電池,你要使用scrollViewWillEndDragging(...)方法爲:

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) { 
    guard let cellWidth = cellWidth else { 
     return 
    } 

    var cellNumber = 0 
    let offsetByCell = targetContentOffset.pointee.x/cellWidth 

    // If the user drag just a little, the scroll view will go to the next cell 
    if offsetByCell > offsetByCell + 0.2 { 
     cellNumber = Int(ceilf(Float(offsetByCell))) 
    } else { 
     cellNumber = Int(floorf(Float(offsetByCell))) 
    } 

    // Avoiding index out of range exception 
    if cellNumber < 0 { 
     cellNumber = 0 
    } 

    // Avoiding index out of range exception 
    if cellNumber >= (collectionView?.numberOfItems(inSection: 0))! { 
     cellNumber = (collectionView?.numberOfItems(inSection: 0))! - 1 
    } 

    // Move to the right position by using the cell width, cell number and considering the minimum line spacing between cells 
    targetContentOffset.pointee.x = cellWidth * CGFloat(cellNumber) + (CGFloat(cellNumber) * (layout?.minimumLineSpacing)!) 

    // Scroll and select the correct item 
    let indexPath = IndexPath(item: cellNumber, section: 0) 
    collectionView?.scrollToItem(at: indexPath, at: .left, animated: true) 
    collectionView?.selectItem(at: indexPath, animated: true, scrollPosition: .left) 
} 

這是你必須在你的視圖控制器中設置的一切。

最後,你必須在你的代碼中做的最後一件事是去你的自定義單元格(在我的例子中爲MyCollectionViewCell)並在我的類中添加一個觀察者到selected屬性,我只是改變背景顏色但你可以放任何你想要的邏輯:

import UIKit 

class MyCollectionViewCell: UICollectionViewCell { 

    override var isSelected: Bool { 
     didSet { 
      backgroundColor = isSelected ? UIColor.blue : UIColor.white 
     } 
    } 

    override init (frame: CGRect){ 
     super.init(frame: frame) 
     backgroundColor = .white 

    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 

} 

希望它可以幫助你實現你所需要的。

+0

由於某種原因,上述不起作用。我所做的是複製和粘貼代碼,看看效果如何將看起來像 –

+0

我已將上述內容複製並粘貼到新項目中,但無法使用。你把它放在一起給我一些想法,或者按照原樣工作,可以看到滾動,如果我想添加我的東西,我可以嗎? –

相關問題