// // ChatMoreMenuView.swift // yinmeng-ios // // Created by MaiMang on 2024/2/29. // import UIKit enum ChatMoreMenuType: Int { case album = 1001 case camera = 1002 } /// 行数 fileprivate let kRowNumber = 2 /// 列数 fileprivate let kColumnNumber = 4 fileprivate let kMoreMenuCellNumberOfOnePage = kRowNumber * kColumnNumber protocol ChatMoreMenuViewDelegate { /// 获取选择的菜单 func menu(_ view: ChatMoreMenuView, DidSelected type: ChatMoreMenuType) } extension ChatMoreMenuViewDelegate { func menu(_ view: ChatMoreMenuView, DidSelected type: ChatMoreMenuType) {} } class ChatMoreMenuView: UIView { // MARK: - lazy var var delegate: ChatMoreMenuViewDelegate? /// 隐藏分页指示器 var hidePageController: Bool = false { didSet { self.pageControl.alpha = self.hidePageController ? 0.0 : 1.0 UIView.animate(withDuration: 0.15, delay: 0, options: .curveEaseOut, animations: { self.pageControl.isHidden = self.hidePageController }, completion: nil) self.collectionView.scrollToItem(at: IndexPath(row: 0, section: 0), at: .centeredHorizontally, animated: false) } } var pageIndicatorTintColor: UIColor? { didSet { guard pageIndicatorTintColor != nil else { return } pageControl.pageIndicatorTintColor = pageIndicatorTintColor } } var currentPageIndicatorTintColor: UIColor? { didSet { guard currentPageIndicatorTintColor != nil else { return } pageControl.currentPageIndicatorTintColor = currentPageIndicatorTintColor } } lazy var dataSource: [ChatMoreMnueConfig] = { let configs = [ ChatMoreMnueConfig(title: "图片", image: "chat_more_album", type: .album), ] return configs }() lazy var collectionView: UICollectionView = { let layout = ChatKeyboardFlowLayout(column: kColumnNumber, row: kRowNumber) // collectionView let collection = UICollectionView(frame: self.bounds, collectionViewLayout: layout) collection.backgroundColor = ThemeColor(hexStr: "#F8F8F8") collection.register(cellType: ChatMoreMenuCell.self) collection.showsHorizontalScrollIndicator = true collection.showsVerticalScrollIndicator = true collection.dataSource = self collection.delegate = self collection.isPagingEnabled = true return collection }() lazy var pageControl: UIPageControl = { let pager = UIPageControl() pager.backgroundColor = .clear pager.pageIndicatorTintColor = .white pager.currentPageIndicatorTintColor = ThemeColor(hexStr: "#000000") pager.currentPage = 0 pager.isHidden = true pager.numberOfPages = self.dataSource.count / kMoreMenuCellNumberOfOnePage + (self.dataSource.count % kMoreMenuCellNumberOfOnePage == 0 ? 0 : 1) return pager }() // MARK: - life cycle override init(frame: CGRect) { super.init(frame: frame) makeUI() reloadData() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) makeUI() reloadData() } func makeUI() { self.backgroundColor = ThemeColor(hexStr: "#F8F8F8") addSubview(pageControl) addSubview(collectionView) pageControl.snp.makeConstraints { make in make.bottom.equalToSuperview().offset(-SafeAraeBottomHeight) make.centerX.equalToSuperview() make.height.equalTo(30) } collectionView.snp.makeConstraints { make in make.top.left.right.equalToSuperview() make.bottom.equalTo(pageControl.snp.top) } } open func reloadData() { self.needsUpdateConstraints() self.layoutIfNeeded() UIView.animate(withDuration: 0.15, delay: 0, options: .curveEaseOut, animations: { self.pageControl.alpha = 1.0 self.pageControl.isHidden = self.dataSource.count > 8 ? false : true }, completion: nil) DispatchQueue.main.async { self.collectionView.reloadData() } } } // MARK: - UICollectionViewDataSource extension ChatMoreMenuView: UICollectionViewDataSource { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return dataSource.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(for: indexPath, cellType: ChatMoreMenuCell.self) if let model = dataSource[safe: indexPath.row] { cell.model = model } return cell } } // MARK: - UICollectionViewDelegate extension ChatMoreMenuView: UICollectionViewDelegate { func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { if let model = dataSource[safe: indexPath.row] { delegate?.menu(self, DidSelected: model.type!) } } } extension ChatMoreMenuView { func scrollViewDidScroll(_ scrollView: UIScrollView) { if scrollView == collectionView { let offsetX = scrollView.contentOffset.x let index = offsetX / ScreenWidth pageControl.currentPage = Int(index) } } } class ChatKeyboardFlowLayout: UICollectionViewFlowLayout { // 保存所有item fileprivate var attributesArr: [UICollectionViewLayoutAttributes] = [] fileprivate var col: Int = 0 fileprivate var row: Int = 0 init(column: Int, row: Int) { super.init() self.col = column self.row = row } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } // MARK: - 重新布局 override func prepare() { super.prepare() let itemWH: CGFloat = ScreenWidth / CGFloat(col) // 设置itemSize itemSize = CGSize(width: itemWH, height: itemWH) minimumLineSpacing = 0 minimumInteritemSpacing = 0 scrollDirection = .horizontal // 设置collectionView属性 collectionView?.isPagingEnabled = true collectionView?.showsHorizontalScrollIndicator = false collectionView?.showsVerticalScrollIndicator = true let insertMargin = (collectionView!.bounds.height - CGFloat(row) * itemWH) * 0.5 collectionView?.contentInset = UIEdgeInsets(top: insertMargin, left: 0, bottom: insertMargin, right: 0) var page = 0 let itemsCount = collectionView?.numberOfItems(inSection: 0) ?? 0 for itemIndex in 0.. [UICollectionViewLayoutAttributes]? { var rectAttributes: [UICollectionViewLayoutAttributes] = [] _ = attributesArr.map({ if rect.contains($0.frame) { rectAttributes.append($0) } }) return rectAttributes } override var collectionViewContentSize: CGSize { let size: CGSize = super.collectionViewContentSize let collectionViewWidth: CGFloat = self.collectionView!.frame.size.width let nbOfScreen: Int = Int(ceil(size.width / collectionViewWidth)) let newSize: CGSize = CGSize(width: collectionViewWidth * CGFloat(nbOfScreen), height: size.height) return newSize } }