使用collectionView制作水平动画指示器

时间:2019-09-25 05:15:43

标签: ios swift uicollectionview

我正在开发App,必须在CollectionviewCell上管理水平指示器,同时滚动CollectionView并选择任何单元格。

This is what I’m looking for(Just focus on Horizontal CollectionView)

正如我已经实现的那样,但是我没有获得确切的功能/行为,并且在滚动时无法将水平指示器粘贴在collectionviewCell上。我只能在CollectionViewCell中做水平指示器时坚持使用,但是在这种情况下,我无法应用滑动动画。 This is what I have implemented

这是我的MENUBAR代码段

    import UIKit

    class MenuBar: UITableViewHeaderFooterView, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UIScrollViewDelegate {

      //MARK:- Properties
      let cellId = "cellId"
      let menuNames = ["Recommeded", "Popular", "Free", "Trending", "Love Songs", " Free Songs"]

      var horizontalBarLeftAnchorConstraint : NSLayoutConstraint?

      lazy var collectionView : UICollectionView = {
          let cv = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
          cv.translatesAutoresizingMaskIntoConstraints = false
          cv.dataSource = self
          cv.delegate = self
          cv.showsHorizontalScrollIndicator = false
          cv.backgroundColor = UIColor.clear
         return cv
      }()

     let horizontalView : UIView = {
         let v = UIView()
         v.backgroundColor = UIColor.red
         v.translatesAutoresizingMaskIntoConstraints = false
         return v
     }()

    //MARK:- default methods
    override init(reuseIdentifier: String?) {
        super.init(reuseIdentifier: reuseIdentifier)

        setupCollectionView()
        setupHorizontalBar()
    }

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

    //MARK:- Functions

    private func setupCollectionView() {
       if let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
           flowLayout.scrollDirection = .horizontal
       }

       addSubview(collectionView)
       collectionView.register(MenuCell.self, forCellWithReuseIdentifier: cellId)

       collectionView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
       collectionView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
       collectionView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
       collectionView.topAnchor.constraint(equalTo: topAnchor).isActive = true
    }


    private func setupHorizontalBar() {
      addSubview(horizontalView)

      let textSize = (menuNames[0] as NSString).size(withAttributes: nil)
      let cellSize = textSize.width + 50
      let indicatorLineWith = 25/2
      let x = (cellSize/2) - CGFloat(indicatorLineWith)


      //x,y,w,h
      horizontalBarLeftAnchorConstraint = 
      horizontalView.leftAnchor.constraint(equalTo: leftAnchor, constant: x )
      horizontalBarLeftAnchorConstraint?.isActive = true
      horizontalView.heightAnchor.constraint(equalToConstant: 5).isActive = true
      horizontalView.widthAnchor.constraint(equalToConstant: 25).isActive = true
      horizontalView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
    }

      //MARK:- CollectionView methods
      func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return menuNames.count
      }

      func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! MenuCell
        cell.menuName = menuNames[indexPath.row]
        return cell
      }

     func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
       let size = (menuNames[indexPath.row] as NSString).size(withAttributes: nil)
       return CGSize(width: (size.width + 50), height: frame.height)
     }

     func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
       return 0
     }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

       //getting Cell size on screen
       let attributes : UICollectionViewLayoutAttributes = collectionView.layoutAttributesForItem(at: indexPath)!
       let indicatorSize = 25/2
       let cellRect = attributes.frame
       let cellFrameInSuperView = collectionView.convert(cellRect, to: collectionView)


       let textSize = (menuNames[indexPath.row] as NSString).size(withAttributes: nil)
       let cellSize = textSize.width + 50


       let x = (CGFloat(cellFrameInSuperView.origin.x) + (cellSize/2)) - CGFloat(indicatorSize)

       horizontalBarLeftAnchorConstraint?.constant = x

       UIView.animate(withDuration: 0.75, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {

          collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
          self.layoutIfNeeded()
       }, completion: nil)

    }
}

这是我的MENUCELL代码段:-

import UIKit

//MARK:- CollectionViewBaseCell
class CollectionViewBaseCell : UICollectionViewCell {

    override init(frame: CGRect) {
        super.init(frame: frame)

        setupViews()
    }

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

    func setupViews() {}
}

//MARK:- MenuCell
class MenuCell : CollectionViewBaseCell {

    //MARK:- Properties
    var menuName : String? {
        didSet {
            label.text = menuName
        }
    }

    let label : UILabel = {
        let lbl = UILabel()
        lbl.translatesAutoresizingMaskIntoConstraints = false
        lbl.text = "Label"
        return lbl
    }()

    //MARK:- default methods
    override func setupViews() {
        addSubview(label)

        //x,y,w,h Constraint
        label.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
        label.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
    }
}

1 个答案:

答案 0 :(得分:3)

请尝试:

    func scrollViewDidScroll(_ scrollView: UIScrollView) { 
        if scrollView == self.collectionView{ 
          print( scrollView.contentOffset.x ) // use this contentOffset 
        }
     }