262 lines
7.2 KiB
Swift
262 lines
7.2 KiB
Swift
//
|
|
// 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..<itemsCount {
|
|
let indexPath = IndexPath(item: itemIndex, section: 0)
|
|
let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
|
|
|
|
page = itemIndex / (col * row)
|
|
// 通过一系列计算, 得到x, y值
|
|
let x = itemSize.width * CGFloat(itemIndex % Int(col)) + (CGFloat(page) * ScreenWidth)
|
|
let y = itemSize.height * CGFloat((itemIndex - page * row * col) / col)
|
|
|
|
attributes.frame = CGRect(x: x, y: y, width: itemSize.width, height: itemSize.height)
|
|
// 把每一个新的属性保存起来
|
|
attributesArr.append(attributes)
|
|
}
|
|
|
|
}
|
|
|
|
override func layoutAttributesForElements(in rect: CGRect) -> [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
|
|
}
|
|
}
|
|
|