|
@@ -0,0 +1,151 @@
|
|
|
|
|
+//
|
|
|
|
|
+// LNRoomBannerView.swift
|
|
|
|
|
+// Gami
|
|
|
|
|
+//
|
|
|
|
|
+// Created by SuperC on 2026/4/9.
|
|
|
|
|
+//
|
|
|
|
|
+
|
|
|
|
|
+import Foundation
|
|
|
|
|
+import UIKit
|
|
|
|
|
+import SnapKit
|
|
|
|
|
+
|
|
|
|
|
+class LNRoomBannerView: UIView {
|
|
|
|
|
+ var onTapBanner: ((_ item: LNBannerInfoVO, _ index: Int) -> Void)?
|
|
|
|
|
+
|
|
|
|
|
+ private let pagerView = LNCyclePager()
|
|
|
|
|
+ private let pageControl = LNCyclePageControl()
|
|
|
|
|
+ private var items: [LNBannerInfoVO] = []
|
|
|
|
|
+ private var loading = false
|
|
|
|
|
+ private var loaded = false
|
|
|
|
|
+
|
|
|
|
|
+ override init(frame: CGRect) {
|
|
|
|
|
+ super.init(frame: frame)
|
|
|
|
|
+ setupViews()
|
|
|
|
|
+ setupPager()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ required init?(coder: NSCoder) {
|
|
|
|
|
+ super.init(coder: coder)
|
|
|
|
|
+ setupViews()
|
|
|
|
|
+ setupPager()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ func loadBanner(adSlot: Int = 2, force: Bool = false) {
|
|
|
|
|
+ if loading { return }
|
|
|
|
|
+ if loaded && !force { return }
|
|
|
|
|
+ loading = true
|
|
|
|
|
+ LNConfigManager.shared.getBannerList(adSlot: adSlot) { [weak self] list in
|
|
|
|
|
+ guard let self else { return }
|
|
|
|
|
+ self.loading = false
|
|
|
|
|
+ self.loaded = true
|
|
|
|
|
+ self.update(items: list ?? [])
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ func update(items: [LNBannerInfoVO]) {
|
|
|
|
|
+ self.items = items
|
|
|
|
|
+ isHidden = items.isEmpty
|
|
|
|
|
+ pageControl.numberOfPages = items.count
|
|
|
|
|
+ pageControl.currentPage = 0
|
|
|
|
|
+ pageControl.isHidden = items.count <= 1
|
|
|
|
|
+ pagerView.reloadData()
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+private extension LNRoomBannerView {
|
|
|
|
|
+ func setupViews() {
|
|
|
|
|
+ isHidden = true
|
|
|
|
|
+ self.backgroundColor = .clear
|
|
|
|
|
+
|
|
|
|
|
+ addSubview(pagerView)
|
|
|
|
|
+ pagerView.snp.makeConstraints { make in
|
|
|
|
|
+ make.top.leading.trailing.equalToSuperview()
|
|
|
|
|
+ make.bottom.equalToSuperview().offset(-12)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ pagerView.addSubview(pageControl)
|
|
|
|
|
+ pageControl.snp.makeConstraints { make in
|
|
|
|
|
+ make.centerX.equalToSuperview()
|
|
|
|
|
+ make.bottom.equalToSuperview()
|
|
|
|
|
+ make.height.equalTo(4)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ func setupPager() {
|
|
|
|
|
+ pagerView.layer.masksToBounds = true
|
|
|
|
|
+ pagerView.layer.cornerRadius = 16
|
|
|
|
|
+ pagerView.isInfiniteLoop = true
|
|
|
|
|
+ pagerView.autoScrollInterval = 3
|
|
|
|
|
+ pagerView.reloadDataNeedResetIndex = true
|
|
|
|
|
+ pagerView.bindPageControl(pageControl)
|
|
|
|
|
+
|
|
|
|
|
+ pagerView.register(LNRoomBannerImageCell.self, forCellWithReuseIdentifier: LNRoomBannerImageCell.className)
|
|
|
|
|
+ pagerView.numberOfItemsProvider = { [weak self] in
|
|
|
|
|
+ self?.items.count ?? 0
|
|
|
|
|
+ }
|
|
|
|
|
+ pagerView.cellProvider = { [weak self] pager, index in
|
|
|
|
|
+ guard let self else { return UICollectionViewCell() }
|
|
|
|
|
+ let cell = pager.dequeueReusableCell(
|
|
|
|
|
+ withReuseIdentifier: LNRoomBannerImageCell.className,
|
|
|
|
|
+ for: index
|
|
|
|
|
+ ) as! LNRoomBannerImageCell
|
|
|
|
|
+ cell.update(items[index])
|
|
|
|
|
+ return cell
|
|
|
|
|
+ }
|
|
|
|
|
+ pagerView.layoutProvider = { [weak self] in
|
|
|
|
|
+ let layout = LNCyclePagerViewLayout()
|
|
|
|
|
+ layout.itemSize = self?.pagerView.bounds.size ?? .zero
|
|
|
|
|
+ layout.itemSpacing = 0
|
|
|
|
|
+ layout.scrollDirection = .horizontal
|
|
|
|
|
+ layout.layoutType = .normal
|
|
|
|
|
+ return layout
|
|
|
|
|
+ }
|
|
|
|
|
+ pagerView.didScrollFromIndexToIndex = { [weak self] _, toIndex in
|
|
|
|
|
+ self?.pageControl.currentPage = toIndex
|
|
|
|
|
+ }
|
|
|
|
|
+ pagerView.didSelectItem = { [weak self] _, index in
|
|
|
|
|
+ guard let self, index >= 0, index < self.items.count else { return }
|
|
|
|
|
+ let item = self.items[index]
|
|
|
|
|
+ self.onTapBanner?(item, index)
|
|
|
|
|
+ guard !item.jump.isEmpty else { return }
|
|
|
|
|
+ self.pushToWebView(.init(url: item.jump))
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ pageControl.pageIndicatorSize = CGSize(width: 4, height: 4)
|
|
|
|
|
+ pageControl.currentPageIndicatorSize = CGSize(width: 4, height: 4)
|
|
|
|
|
+ pageControl.pageIndicatorTintColor = .init(hex: "#FFFFFF4D")
|
|
|
|
|
+ pageControl.currentPageIndicatorTintColor = .white
|
|
|
|
|
+ pageControl.pageIndicatorSpacing = 5
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+private final class LNRoomBannerImageCell: UICollectionViewCell {
|
|
|
|
|
+ private let imageView = UIImageView()
|
|
|
|
|
+
|
|
|
|
|
+ override init(frame: CGRect) {
|
|
|
|
|
+ super.init(frame: frame)
|
|
|
|
|
+ contentView.layer.masksToBounds = true
|
|
|
|
|
+ contentView.layer.cornerRadius = 12
|
|
|
|
|
+
|
|
|
|
|
+ imageView.layer.masksToBounds = true
|
|
|
|
|
+ imageView.layer.cornerRadius = 16
|
|
|
|
|
+ imageView.contentMode = .scaleAspectFill
|
|
|
|
|
+ contentView.addSubview(imageView)
|
|
|
|
|
+ imageView.snp.makeConstraints { make in
|
|
|
|
|
+ make.edges.equalToSuperview()
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ required init?(coder: NSCoder) {
|
|
|
|
|
+ fatalError("init(coder:) has not been implemented")
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ override func prepareForReuse() {
|
|
|
|
|
+ super.prepareForReuse()
|
|
|
|
|
+ imageView.image = nil
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ func update(_ item: LNBannerInfoVO) {
|
|
|
|
|
+ imageView.sd_setImage(with: URL(string: item.img))
|
|
|
|
|
+ }
|
|
|
|
|
+}
|