// // SelfRenderView.swift // RoderickRalph // // Created by Neoa on 2025/1/11. // import UIKit import AnyThinkNative // 定义常量 let SelfRenderViewWidth = UIScreen.main.bounds.width let SelfRenderViewHeight: CGFloat = 170 let SelfRenderViewMediaViewWidth = UIScreen.main.bounds.width let SelfRenderViewMediaViewHeight: CGFloat = 160 class SelfRenderView: UIView { // MARK: - UI Components /// 广告主 var advertiserLabel: UILabel! /// 内容 var textLabel: UILabel! /// 标题 var titleLabel: UILabel! /// 类似"点我下载"按钮上面的口号 var ctaLabel: UILabel! /// 评分 var ratingLabel: UILabel! /// 推广应用icon var iconImageView: UIImageView! /// 主图 var mainImageView: UIImageView! /// 广告平台logo标识 var logoImageView: UIImageView! /// 关闭按钮 var dislikeButton: UIButton! /// 媒体视图 var mediaView: UIView? // only for yandex native var domainLabel: UILabel! var warningLabel: UILabel! // MARK: - Private Properties private var nativeAdOffer: ATNativeAdOffer? // MARK: - Initialization override init(frame: CGRect) { super.init(frame: frame) setupUI() } required init?(coder: NSCoder) { super.init(coder: coder) setupUI() } convenience init(offer: ATNativeAdOffer) { self.init(frame: .zero) self.nativeAdOffer = offer setupUI() } deinit { print("🔥---SelfRenderView--dealloc") } // MARK: - UI Setup private func setupUI() { // 随机背景色 backgroundColor = randomColor() addView() makeConstraintsForSubviews() setupUIWithOffer() } private func addView() { // // 广告主标签 // advertiserLabel = UILabel() // advertiserLabel.font = UIFont.boldSystemFont(ofSize: 15.0) // advertiserLabel.textColor = .black // advertiserLabel.textAlignment = .left // advertiserLabel.translatesAutoresizingMaskIntoConstraints = false // addSubview(advertiserLabel) // 标题标签 titleLabel = UILabel() titleLabel.font = UIFont.systemFont(ofSize: 14.0) titleLabel.textColor = .gray titleLabel.textAlignment = .left titleLabel.translatesAutoresizingMaskIntoConstraints = false addSubview(titleLabel) // 内容标签 textLabel = UILabel() textLabel.font = UIFont.boldSystemFont(ofSize: 16.0) textLabel.textColor = .black textLabel.numberOfLines = 0 textLabel.translatesAutoresizingMaskIntoConstraints = false addSubview(textLabel) // // CTA标签 // ctaLabel = UILabel() // ctaLabel.font = UIFont.systemFont(ofSize: 15.0) // ctaLabel.textColor = .white // ctaLabel.backgroundColor = .blue // ctaLabel.textAlignment = .center // ctaLabel.translatesAutoresizingMaskIntoConstraints = false // addSubview(ctaLabel) // // // 评分标签 // ratingLabel = UILabel() // ratingLabel.font = UIFont.systemFont(ofSize: 15.0) // ratingLabel.textColor = .systemYellow // ratingLabel.translatesAutoresizingMaskIntoConstraints = false // addSubview(ratingLabel) // // 域名标签 (yandex) // domainLabel = UILabel() // domainLabel.font = UIFont.systemFont(ofSize: 15.0) // domainLabel.textColor = .black // domainLabel.translatesAutoresizingMaskIntoConstraints = false // addSubview(domainLabel) // // // 警告标签 (yandex) // warningLabel = UILabel() // warningLabel.font = UIFont.systemFont(ofSize: 15.0) // warningLabel.textColor = .black // warningLabel.translatesAutoresizingMaskIntoConstraints = false // addSubview(warningLabel) // // 图标 // iconImageView = UIImageView() // iconImageView.layer.cornerRadius = 4.0 // iconImageView.layer.masksToBounds = true // iconImageView.contentMode = .scaleAspectFit // iconImageView.translatesAutoresizingMaskIntoConstraints = false // addSubview(iconImageView) // 主图 mainImageView = UIImageView() mainImageView.contentMode = .scaleAspectFit mainImageView.translatesAutoresizingMaskIntoConstraints = false addSubview(mainImageView) // Logo // logoImageView = UIImageView() // logoImageView.contentMode = .scaleAspectFit // logoImageView.tag = 110220 // logoImageView.translatesAutoresizingMaskIntoConstraints = false // addSubview(logoImageView) // 关闭按钮 dislikeButton = UIButton(type: .custom) dislikeButton.backgroundColor = .white // 尝试从AnyThinkSDK bundle中获取关闭按钮图片 // if let bundlePath = Bundle.main.path(forResource: "AnyThinkSDK", ofType: "bundle"), // let bundle = Bundle(path: bundlePath), // let closeImg = UIImage(named: "offer_video_close", in: bundle, compatibleWith: nil) { // dislikeButton.setImage(closeImg, for: .normal) // } else { dislikeButton.setTitle("×", for: .normal) dislikeButton.setTitleColor(.gray, for: .normal) dislikeButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 18) // } dislikeButton.translatesAutoresizingMaskIntoConstraints = false addSubview(dislikeButton) addUserInteraction() } private func addUserInteraction() { // ctaLabel.isUserInteractionEnabled = true // advertiserLabel.isUserInteractionEnabled = true titleLabel.isUserInteractionEnabled = true textLabel.isUserInteractionEnabled = true // ratingLabel.isUserInteractionEnabled = true // domainLabel.isUserInteractionEnabled = true // warningLabel.isUserInteractionEnabled = true // iconImageView.isUserInteractionEnabled = true mainImageView.isUserInteractionEnabled = true // logoImageView.isUserInteractionEnabled = true } private func setupUIWithOffer() { guard let offer = nativeAdOffer else { return } // 设置图标 // if let icon = offer.nativeAd.icon { // iconImageView.image = icon // } else if let iconUrl = offer.nativeAd.iconUrl, let url = URL(string: iconUrl) { // loadImage(from: url, into: iconImageView) // print("🔥AnyThinkDemo::iconUrl:\(iconUrl)") // } // 设置主图 if let mainImage = offer.nativeAd.mainImage { mainImageView.image = mainImage } else if let imageUrl = offer.nativeAd.imageUrl, let url = URL(string: imageUrl) { loadImage(from: url, into: mainImageView) print("🔥AnyThinkDemo::imageUrl:\(imageUrl)") } // // 设置Logo // if let logoUrl = offer.nativeAd.logoUrl, !logoUrl.isEmpty { // print("🔥----logoUrl:\(logoUrl)") // if let url = URL(string: logoUrl) { // loadImage(from: url, into: logoImageView) // } // } else if let logo = offer.nativeAd.logo { // print("🔥----logo:\(logo)") // logoImageView.image = logo // } else { // // 根据networkFirmID设置默认平台logo //// if offer.networkFirmID == ATNetworkFirmIDTypeCSJ { //// logoImageView.image = UIImage(named: "tt_ad_logo_new") //// } // } // 设置文本内容 // advertiserLabel.text = offer.nativeAd.advertiser titleLabel.text = offer.nativeAd.title textLabel.text = offer.nativeAd.mainText // ctaLabel.text = offer.nativeAd.ctaText ?? "查看详情"// : offer.nativeAd.ctaText // ratingLabel.text = "评分:\(offer.nativeAd.rating?.stringValue ?? "暂无评分")" // yandex平台支持 // domainLabel.text = offer.nativeAd.domain // warningLabel.text = offer.nativeAd.warning print("🔥AnythinkDemo::native domain:\(offer.nativeAd.domain ?? ""); warning:\(offer.nativeAd.warning ?? "")") print("🔥AnythinkDemo::native文本内容title:\(offer.nativeAd.title ?? ""); text:\(offer.nativeAd.mainText ?? ""); cta:\(offer.nativeAd.ctaText ?? "")") } private func makeConstraintsForSubviews() { backgroundColor = .white titleLabel.backgroundColor = .white textLabel.backgroundColor = .white NSLayoutConstraint.activate([ // 主图约束 mainImageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 12), // mainImageView.centerYAnchor.constraint(equalTo: centerYAnchor), mainImageView.topAnchor.constraint(equalTo: topAnchor, constant: 10), mainImageView.widthAnchor.constraint(equalToConstant: 200), mainImageView.heightAnchor.constraint(equalToConstant: 150), // // Logo约束 // logoImageView.heightAnchor.constraint(equalToConstant: 25), // logoImageView.widthAnchor.constraint(equalToConstant: 25), // logoImageView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -5), // logoImageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 5), // 内容约束 textLabel.leadingAnchor.constraint(equalTo: mainImageView.trailingAnchor, constant: 8), textLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -30), // textLabel.heightAnchor.constraint(equalToConstant: 20), textLabel.topAnchor.constraint(equalTo: mainImageView.topAnchor, constant: 10), // 标题约束 titleLabel.leadingAnchor.constraint(equalTo: mainImageView.trailingAnchor, constant: 8), titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -36), titleLabel.heightAnchor.constraint(equalToConstant: 20), titleLabel.bottomAnchor.constraint(equalTo: mainImageView.bottomAnchor,constant: 0), // // CTA约束 // ctaLabel.topAnchor.constraint(equalTo: textLabel.bottomAnchor, constant: 5), // ctaLabel.widthAnchor.constraint(equalToConstant: 100), // ctaLabel.heightAnchor.constraint(equalToConstant: ctaLabel.font.lineHeight), // ctaLabel.leadingAnchor.constraint(equalTo: textLabel.leadingAnchor), // // 评分约束 // ratingLabel.leadingAnchor.constraint(equalTo: ctaLabel.trailingAnchor, constant: 20), // ratingLabel.heightAnchor.constraint(equalToConstant: ratingLabel.font.lineHeight), // ratingLabel.topAnchor.constraint(equalTo: ctaLabel.topAnchor), // // // 域名约束 // domainLabel.leadingAnchor.constraint(equalTo: ratingLabel.trailingAnchor, constant: 20), // domainLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -40), // domainLabel.topAnchor.constraint(equalTo: ctaLabel.topAnchor), // domainLabel.heightAnchor.constraint(equalToConstant: 40), // // // 广告主约束 // advertiserLabel.heightAnchor.constraint(equalToConstant: advertiserLabel.font.lineHeight), // advertiserLabel.leadingAnchor.constraint(equalTo: ctaLabel.leadingAnchor), // advertiserLabel.topAnchor.constraint(equalTo: ctaLabel.bottomAnchor, constant: 5), // // // 图标约束 // iconImageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20), // iconImageView.heightAnchor.constraint(equalToConstant: 75), // iconImageView.widthAnchor.constraint(equalToConstant: 75), // iconImageView.topAnchor.constraint(equalTo: topAnchor, constant: 20), // // // // 警告标签约束 // warningLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 5), // warningLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -5), // warningLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -5), // warningLabel.heightAnchor.constraint(equalToConstant: 40), // 关闭按钮约束 dislikeButton.heightAnchor.constraint(equalToConstant: 20), dislikeButton.widthAnchor.constraint(equalToConstant: 20), dislikeButton.topAnchor.constraint(equalTo: topAnchor, constant: 5), dislikeButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -10) ]) } // MARK: - Media View func setMediaView(_ mediaView: UIView?) { self.mediaView = mediaView if let mediaView = mediaView { addSubview(mediaView) mediaView.translatesAutoresizingMaskIntoConstraints = false // 给mediaView设置约束,与mainImageView相同 NSLayoutConstraint.activate([ mediaView.leadingAnchor.constraint(equalTo: mainImageView.leadingAnchor), mediaView.trailingAnchor.constraint(equalTo: mainImageView.trailingAnchor), mediaView.topAnchor.constraint(equalTo: mainImageView.topAnchor), mediaView.bottomAnchor.constraint(equalTo: mainImageView.bottomAnchor) ]) } } // MARK: - Helper Methods private func randomColor() -> UIColor { let r = CGFloat.random(in: 0...255) let g = CGFloat.random(in: 0...255) let b = CGFloat.random(in: 0...255) let a = CGFloat.random(in: 0...255) return UIColor(red: r/255.0, green: g/255.0, blue: b/255.0, alpha: a/255.0) } private func loadImage(from url: URL, into imageView: UIImageView) { URLSession.shared.dataTask(with: url) { data, _, _ in guard let data = data, let image = UIImage(data: data) else { return } DispatchQueue.main.async { imageView.image = image } }.resume() } // MARK: - Cleanup func destory() { // 及时销毁offer nativeAdOffer = nil mediaView?.removeFromSuperview() mediaView = nil } }