170 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Swift
		
	
	
			
		
		
	
	
			170 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Swift
		
	
	
| //
 | |
| //  GuruBannerCoordinator.swift
 | |
| //  Pods
 | |
| //
 | |
| //  Created by 250102 on 2025/5/9.
 | |
| //
 | |
| 
 | |
| protocol GuruBannerView {
 | |
|     
 | |
|     func view() -> UIView
 | |
|     func setPlacementName(placement: String)
 | |
|     func onShow();
 | |
|     func onHide();
 | |
| }
 | |
| 
 | |
| class GuruBannerCoordinator<T: GuruBannerView> {
 | |
|     
 | |
|     private let viewController: UIViewController
 | |
|     public private(set) var bannerAd: T
 | |
|     private var bannerPosition: BannerPosition { return lastShowRequest?.position ?? BannerPosition.bottom }
 | |
|     private var bannerOffset: CGFloat { return CGFloat(lastShowRequest?.offset ?? 0.0) }
 | |
|     private var lastShowRequest: BannerShowRequest? = nil
 | |
| 
 | |
|     public private(set) var orientation: ScreenOrientation = .portrait
 | |
|         
 | |
|     public init(viewController: UIViewController, bannerAd: T, contentId: Int) {
 | |
|         self.viewController = viewController
 | |
|         self.bannerAd = bannerAd
 | |
|     }
 | |
|     
 | |
|     public func logInfo(_ message: String) {
 | |
|         Logger.i(tag: "GuruBannerCoordinator", message: "\(message)")
 | |
|     }
 | |
|     public func logWarn(_ message: String) {
 | |
|         Logger.w(tag: "GuruBannerCoordinator", message: "\(message)")
 | |
|     }
 | |
|     
 | |
|     public func show(_ request: BannerShowRequest? = nil) -> Bool {
 | |
|         var shouldReattach = false
 | |
|         
 | |
|         // Check if position or offset has changed
 | |
|         if let newOffset = request?.offset, newOffset != Float(bannerOffset) {
 | |
|             shouldReattach = true
 | |
|         }
 | |
|         
 | |
|         if let newPosition = request?.position, newPosition != bannerPosition {
 | |
|             shouldReattach = true
 | |
|         }
 | |
|         
 | |
|         lastShowRequest = request
 | |
|         
 | |
|         guard let container = viewController.viewIfLoaded else {
 | |
|             logWarn("viewController.view is nil, returns false")
 | |
|             return false
 | |
|         }
 | |
|         let bannerAdView = bannerAd.view()
 | |
|         
 | |
|         var attached = container.subviews.contains(bannerAdView)
 | |
|         
 | |
|         // If we already have a view and parameters changed, remove it
 | |
|         if shouldReattach || !attached {
 | |
|             logInfo("Parameters changed! Re-attaching view!")
 | |
|             if(attached) {
 | |
|                 bannerAdView.removeFromSuperview()
 | |
|             }
 | |
|             let isTablet = UIDevice.current.userInterfaceIdiom == .pad
 | |
|             let bannerHeight: CGFloat = isTablet ? 90 : 50
 | |
|             let screenWidth = min(viewController.view.bounds.width, viewController.view.bounds.height)
 | |
|             
 | |
|             container.addSubview(bannerAdView)
 | |
|             bannerAdView.translatesAutoresizingMaskIntoConstraints = false
 | |
|             
 | |
|             
 | |
|             logInfo("BannerAd show!!! bannerSize: \(screenWidth)x\(bannerHeight)")
 | |
|                         
 | |
|             if let placement = lastShowRequest?.placement {
 | |
|                 bannerAd.setPlacementName(placement: placement)
 | |
|             }
 | |
|             // Configure banner position and rotation
 | |
|             var transform = CGAffineTransform.identity
 | |
|             switch bannerPosition {
 | |
|             case .start:
 | |
|                 transform = CGAffineTransform(rotationAngle: .pi / 2)
 | |
|                 NSLayoutConstraint.activate([
 | |
|                     bannerAdView.leadingAnchor.constraint(equalTo: container.safeAreaLayoutGuide.leadingAnchor, constant: bannerOffset),
 | |
|                     bannerAdView.centerYAnchor.constraint(equalTo: container.centerYAnchor),
 | |
|                     bannerAdView.widthAnchor.constraint(equalToConstant: screenWidth),
 | |
|                     bannerAdView.heightAnchor.constraint(equalToConstant: bannerHeight)
 | |
|                 ])
 | |
|                 
 | |
|             case .end:
 | |
|                 transform = CGAffineTransform(rotationAngle: -(.pi / 2))
 | |
|                 NSLayoutConstraint.activate([
 | |
|                     bannerAdView.trailingAnchor.constraint(equalTo: container.safeAreaLayoutGuide.trailingAnchor, constant: -bannerOffset),
 | |
|                     bannerAdView.centerYAnchor.constraint(equalTo: container.centerYAnchor),
 | |
|                     
 | |
|                     bannerAdView.widthAnchor.constraint(equalToConstant: screenWidth),
 | |
|                     bannerAdView.heightAnchor.constraint(equalToConstant: bannerHeight)
 | |
|                 ])
 | |
|                 
 | |
|             case .top:
 | |
|                 transform = CGAffineTransform(rotationAngle: 0)
 | |
|                 
 | |
|                 NSLayoutConstraint.activate([
 | |
|                     bannerAdView.centerXAnchor.constraint(equalTo: container.centerXAnchor),
 | |
|                     bannerAdView.topAnchor.constraint(equalTo: container.safeAreaLayoutGuide.topAnchor, constant: bannerOffset),
 | |
|                     
 | |
|                     bannerAdView.heightAnchor.constraint(equalToConstant: bannerHeight),
 | |
|                     bannerAdView.widthAnchor.constraint(equalToConstant: screenWidth),
 | |
|                 ])
 | |
|                 
 | |
|             default:
 | |
|                 transform = CGAffineTransform(rotationAngle: 0)
 | |
|                 NSLayoutConstraint.activate([
 | |
|                     bannerAdView.centerXAnchor.constraint(equalTo: container.centerXAnchor),
 | |
|                     bannerAdView.bottomAnchor.constraint(equalTo: container.safeAreaLayoutGuide.bottomAnchor, constant: -bannerOffset),
 | |
|                     
 | |
|                     bannerAdView.heightAnchor.constraint(equalToConstant: bannerHeight),
 | |
|                     bannerAdView.widthAnchor.constraint(equalToConstant: screenWidth)
 | |
|                 ])
 | |
|             }
 | |
|             
 | |
|             bannerAdView.transform = transform
 | |
|             bannerAdView.isHidden = false
 | |
|             bannerAd.onShow()
 | |
|         } else {
 | |
|             bannerAd.view().isHidden = false
 | |
|             bannerAd.onShow()
 | |
|         }
 | |
|         
 | |
|         if let placement = request?.placement {
 | |
|             bannerAd.setPlacementName(placement: placement)
 | |
|         }
 | |
|         
 | |
|         return true
 | |
|     }
 | |
|     
 | |
|     public func hide() -> Bool {
 | |
|         guard let _ = viewController.view.superview?.contains(bannerAd.view()) else {
 | |
|             return true
 | |
|         }
 | |
| 
 | |
|         bannerAd.view().isHidden = true
 | |
|         bannerAd.onHide()
 | |
|         
 | |
|         return true
 | |
|     }
 | |
|     
 | |
|     public func destroy() -> Bool {
 | |
|         bannerAd.view().removeFromSuperview()
 | |
| 
 | |
|         return true
 | |
|     }
 | |
|     
 | |
|     public func updateOrientation(orientation: ScreenOrientation) -> Bool {
 | |
|         if let _ = viewController.view.superview?.contains(bannerAd.view()), self.orientation != orientation {
 | |
|             let isVisible = !bannerAd.view().isHidden
 | |
|             
 | |
|             bannerAd.onHide()
 | |
|             bannerAd.view().isHidden = true
 | |
|             if isVisible {
 | |
|                 return show()
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         self.orientation = orientation
 | |
|         return true
 | |
|     }
 | |
| }
 |