// // HomeCommonAppsGridView.swift // suixinkan // import SnapKit import UIKit /// 首页常用应用网格。 final class HomeCommonAppsGridView: UIView { var onMenuSelected: ((HomeMenuItem) -> Void)? private enum Section { case main } private enum Item: Hashable { case menu(HomeMenuItem) } private var menus: [HomeMenuItem] = [] private let titleLabel = UILabel() private lazy var collectionView: UICollectionView = { let itemSize = NSCollectionLayoutSize( widthDimension: .fractionalWidth(0.25), heightDimension: .absolute(88) ) let item = NSCollectionLayoutItem(layoutSize: itemSize) let groupSize = NSCollectionLayoutSize( widthDimension: .fractionalWidth(1), heightDimension: .absolute(88) ) let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item]) let section = NSCollectionLayoutSection(group: group) let layout = UICollectionViewCompositionalLayout(section: section) return UICollectionView(frame: .zero, collectionViewLayout: layout) }() private lazy var dataSource = UICollectionViewDiffableDataSource(collectionView: collectionView) { collectionView, indexPath, item in let cell = collectionView.dequeueReusableCell( withReuseIdentifier: HomeMenuCell.reuseIdentifier, for: indexPath ) as! HomeMenuCell if case let .menu(menu) = item { cell.apply(menu: menu) } return cell } override init(frame: CGRect) { super.init(frame: frame) titleLabel.text = "常用应用" titleLabel.font = .app(.title) titleLabel.textColor = AppColor.textPrimary collectionView.backgroundColor = .clear collectionView.delegate = self collectionView.register(HomeMenuCell.self, forCellWithReuseIdentifier: HomeMenuCell.reuseIdentifier) addSubview(titleLabel) addSubview(collectionView) titleLabel.snp.makeConstraints { make in make.top.leading.trailing.equalToSuperview() } collectionView.snp.makeConstraints { make in make.top.equalTo(titleLabel.snp.bottom).offset(AppSpacing.sm) make.leading.trailing.bottom.equalToSuperview() make.height.equalTo(88) } } @available(*, unavailable) required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } func apply(menus: [HomeMenuItem]) { self.menus = menus + [.moreFunctions] var snapshot = NSDiffableDataSourceSnapshot() snapshot.appendSections([.main]) snapshot.appendItems(self.menus.map { Item.menu($0) }) dataSource.apply(snapshot, animatingDifferences: false) } } extension HomeCommonAppsGridView: UICollectionViewDelegate { func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { guard indexPath.item < menus.count else { return } onMenuSelected?(menus[indexPath.item]) } } /// 首页菜单 cell。 final class HomeMenuCell: UICollectionViewCell { static let reuseIdentifier = "HomeMenuCell" private let iconView = UIImageView() private let titleLabel = UILabel() override init(frame: CGRect) { super.init(frame: frame) iconView.tintColor = AppColor.primary iconView.contentMode = .scaleAspectFit titleLabel.font = .app(.caption) titleLabel.textColor = AppColor.textPrimary titleLabel.textAlignment = .center titleLabel.numberOfLines = 2 contentView.addSubview(iconView) contentView.addSubview(titleLabel) iconView.snp.makeConstraints { make in make.top.equalToSuperview().offset(AppSpacing.xs) make.centerX.equalToSuperview() make.width.height.equalTo(28) } titleLabel.snp.makeConstraints { make in make.top.equalTo(iconView.snp.bottom).offset(AppSpacing.xs) make.leading.trailing.equalToSuperview().inset(AppSpacing.xxs) } } @available(*, unavailable) required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } func apply(menu: HomeMenuItem) { iconView.image = UIImage(systemName: menu.iconName) titleLabel.text = menu.title } }