Files
yingmeng-ios-switf/yinmeng-ios/Modules/Chat/Keyboard/ChatMoreMenuView.swift
2024-03-01 14:22:06 +08:00

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
}
}