iOS AdMob激励视频:实现限时可跳过/延迟关闭广告功能
Hey there! Let's work through your request to modify the AdMob rewarded video ad's close button behavior—either delaying its availability or replacing it with a "Skip Ad" button. First, a quick heads-up: AdMob's native ad UI elements are controlled by their SDK, so any customization needs to align with AdMob's policies to avoid account issues. With that in mind, here are your options:
Option 1: Delay the Close Button's Availability
You can disable the default close button when the ad opens, then re-enable it after a set time (like 5 seconds). This requires traversing the ad's view hierarchy to find the close button—note that AdMob's view structure might change with SDK updates, so you may need to adjust this logic periodically.
// Implement this in your GADRewardBasedVideoAdDelegate method func rewardBasedVideoAdDidOpen(_ rewardBasedVideoAd: GADRewardBasedVideoAd) { guard let adRootView = rewardBasedVideoAd.rootViewController?.view else { return } // Recursively search for the close button in the ad's view hierarchy func findCloseButton(in view: UIView) -> UIButton? { for subview in view.subviews { if let button = subview as? UIButton { // Adjust the check based on your ad's actual close button (title, image, etc.) if button.titleLabel?.text?.lowercased() == "close" || button.currentImage != nil { return button } } if let foundButton = findCloseButton(in: subview) { return foundButton } } return nil } if let closeButton = findCloseButton(in: adRootView) { closeButton.isEnabled = false // Re-enable the button after 5 seconds Timer.scheduledTimer(withTimeInterval: 5.0, repeats: false) { _ in closeButton.isEnabled = true } } }
Notes:
- Test this thoroughly after any AdMob SDK updates, as view structures can shift.
- Don't set an excessively long delay—this can hurt user experience and may violate policies.
Option 2: Replace with a "Skip Ad" Button
For this approach, we'll hide the default close button and add a custom "Skip Ad" button that becomes active after a delay. Again, ensure this follows AdMob's policies (skip buttons are typically allowed after a short mandatory viewing period).
func rewardBasedVideoAdDidOpen(_ rewardBasedVideoAd: GADRewardBasedVideoAd) { guard let adViewController = rewardBasedVideoAd.rootViewController else { return } let adView = adViewController.view // Hide the original close button func hideDefaultCloseButton(in view: UIView) { for subview in view.subviews { if let button = subview as? UIButton { if button.titleLabel?.text?.lowercased() == "close" || button.currentImage != nil { button.isHidden = true break } } hideDefaultCloseButton(in: subview) } } hideDefaultCloseButton(in: adView!) // Create custom Skip Ad button let skipButton = UIButton(type: .system) skipButton.setTitle("Skip Ad", for: .normal) skipButton.titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: .medium) skipButton.backgroundColor = UIColor(white: 0.2, alpha: 0.8) skipButton.setTitleColor(.white, for: .normal) skipButton.layer.cornerRadius = 8 skipButton.isEnabled = false // Add button to ad view and set constraints adView?.addSubview(skipButton) skipButton.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ skipButton.trailingAnchor.constraint(equalTo: adView!.trailingAnchor, constant: -16), skipButton.bottomAnchor.constraint(equalTo: adView!.bottomAnchor, constant: -32), skipButton.widthAnchor.constraint(equalToConstant: 100), skipButton.heightAnchor.constraint(equalToConstant: 40) ]) // Enable button after 5 seconds Timer.scheduledTimer(withTimeInterval: 5.0, repeats: false) { _ in skipButton.isEnabled = true } // Handle skip button tap skipButton.addTarget(self, action: #selector(handleSkipAdTap), for: .touchUpInside) } @objc private func handleSkipAdTap() { if rewardBasedVideo.isReady { rewardBasedVideo.pause() rewardBasedVideo.rootViewController?.dismiss(animated: true) } }
Notes:
- Custom buttons should clearly communicate their purpose—avoid misleading users.
- If you're still using
GADRewardBasedVideoAd, consider migrating to the newerGADRewardedAdSDK (the old one is deprecated). Here's a quick snippet for the new SDK:
var rewardedAd: GADRewardedAd? // Load ad func loadRewardedAd() { GADRewardedAd.load(withAdUnitID: GOOGLE_AD_UNIT_ID, request: GADRequest()) { ad, error in if let error = error { print("Ad load failed: \(error.localizedDescription)") return } self.rewardedAd = ad self.rewardedAd?.fullScreenContentDelegate = self } } // Present ad if let ad = rewardedAd { ad.present(fromRootViewController: self) { let reward = ad.adReward print("User earned \(reward.amount) \(reward.type)") } }
You'd use the fullScreenContentDidPresent(_:) delegate method instead of rewardBasedVideoAdDidOpen(_:) to customize the button in the new SDK.
内容的提问来源于stack exchange,提问作者Pramod More

