一旦 iAd 的委托方法被调用,iAd 就不会异步显示
iAd doesn't show asynchronously once its delegate method is called
我已经在 swift 中复制了 iAdSuite with Storyboards 并且 iAd 在所有视图控制器上都可以正常工作,除了当调用委托方法 bannerViewDidLoadAd(banner: ADBannerView!)
时横幅视图不会出现即刻。我必须旋转模拟器或转到另一个选项卡才能显示它。
我认为这是 Objective-C 中我无法 "translate" 到 swift 的 Apple 示例代码的一部分?这很可能导致 iAd 在加载后不异步显示...
+ (BannerViewManager *)sharedInstance
{
static BannerViewManager *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[BannerViewManager alloc] init];
});
return sharedInstance;
}
这是我的 BannerViewManager
class 和 ADBannerViewDelegate
方法。
class BannerViewManager: NSObject, ADBannerViewDelegate {
// MARK: - Shared instance
static let sharedInstance = BannerViewManager()
var bannerView: ADBannerView!
var bannerViewControllers: NSMutableSet!
override init() {
super.init()
bannerView = ADBannerView(adType: .Banner)
bannerViewControllers = NSMutableSet()
bannerView.delegate = self
}
func addBannerViewController(controller: BannerViewController) {
bannerViewControllers.addObject(controller)
}
func removeBannerViewController(controller: BannerViewController) {
bannerViewControllers.removeObject(controller)
}
// MARK: - Ad banner view delegate methods
func bannerViewDidLoadAd(banner: ADBannerView!) {
NSLog("bannerViewDidLoadAd")
for bannerViewController in bannerViewControllers {
(bannerViewController as! BannerViewController).updateLayout()
}
}
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
NSLog("didFailToReceiveAdWithError %@", error);
for bannerViewController in bannerViewControllers {
(bannerViewController as! BannerViewController).updateLayout()
}
}
func bannerViewActionShouldBegin(banner: ADBannerView!, willLeaveApplication willLeave: Bool) -> Bool {
NSNotificationCenter.defaultCenter().postNotificationName(BannerViewActionWillBegin, object: self)
return true
}
func bannerViewActionDidFinish(banner: ADBannerView!) {
NSNotificationCenter.defaultCenter().postNotificationName(BannerViewActionDidFinish, object: self)
}
}
编辑
我已经设法使用 this post on SO 将上面的 objective-C 代码转换为 swift,但我仍然遇到同样的问题。 iAd 在加载后不会出现。必须对视图进行某种更改才能实现,旋转设备或点击另一个选项卡等...
所以现在我的 sharedInstance
看起来像这样:
static var sharedInstance: BannerViewManager {
struct Static {
static var onceToken: dispatch_once_t = 0
static var instance: BannerViewManager? = nil
}
dispatch_once(&Static.onceToken) {
Static.instance = BannerViewManager()
}
return Static.instance!
}
我想我明白问题出在哪里了。它与我初始化 BannerViewManager
class 的共享实例的方式无关。事实上,无论是使用 dispatch_once
还是新的 swift 2.0 方式,结果都给出了完全相同的行为。
导致 iAd 在调用 bannerViewDidLoadAd
时没有立即显示的原因是 viewDidLayoutSubviews
实际上从未被调用过!
我不得不到处添加一些打印语句。在我的代码和Apple示例代码中都得出了这个结论。
所以 setNeedsLayout
而不是 layoutIfNeeded
强制触发 viewDidLayoutSubviews
- 一般在bannerViewDidLoadAd中打断点,回调函数类似
- 检查你是否有像 swift 中那样的代理 class YourClassViewController: UIViewController, ADBannerViewDelegate.
- 检查你的情况,你说 "I have to either rotate the simulator or go to another tab so that it appears",所以可能是哪种方法造成的。我知道你已经猜到了。
- 阅读文档,分析。
我已经在 swift 中复制了 iAdSuite with Storyboards 并且 iAd 在所有视图控制器上都可以正常工作,除了当调用委托方法 bannerViewDidLoadAd(banner: ADBannerView!)
时横幅视图不会出现即刻。我必须旋转模拟器或转到另一个选项卡才能显示它。
我认为这是 Objective-C 中我无法 "translate" 到 swift 的 Apple 示例代码的一部分?这很可能导致 iAd 在加载后不异步显示...
+ (BannerViewManager *)sharedInstance
{
static BannerViewManager *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[BannerViewManager alloc] init];
});
return sharedInstance;
}
这是我的 BannerViewManager
class 和 ADBannerViewDelegate
方法。
class BannerViewManager: NSObject, ADBannerViewDelegate {
// MARK: - Shared instance
static let sharedInstance = BannerViewManager()
var bannerView: ADBannerView!
var bannerViewControllers: NSMutableSet!
override init() {
super.init()
bannerView = ADBannerView(adType: .Banner)
bannerViewControllers = NSMutableSet()
bannerView.delegate = self
}
func addBannerViewController(controller: BannerViewController) {
bannerViewControllers.addObject(controller)
}
func removeBannerViewController(controller: BannerViewController) {
bannerViewControllers.removeObject(controller)
}
// MARK: - Ad banner view delegate methods
func bannerViewDidLoadAd(banner: ADBannerView!) {
NSLog("bannerViewDidLoadAd")
for bannerViewController in bannerViewControllers {
(bannerViewController as! BannerViewController).updateLayout()
}
}
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
NSLog("didFailToReceiveAdWithError %@", error);
for bannerViewController in bannerViewControllers {
(bannerViewController as! BannerViewController).updateLayout()
}
}
func bannerViewActionShouldBegin(banner: ADBannerView!, willLeaveApplication willLeave: Bool) -> Bool {
NSNotificationCenter.defaultCenter().postNotificationName(BannerViewActionWillBegin, object: self)
return true
}
func bannerViewActionDidFinish(banner: ADBannerView!) {
NSNotificationCenter.defaultCenter().postNotificationName(BannerViewActionDidFinish, object: self)
}
}
编辑
我已经设法使用 this post on SO 将上面的 objective-C 代码转换为 swift,但我仍然遇到同样的问题。 iAd 在加载后不会出现。必须对视图进行某种更改才能实现,旋转设备或点击另一个选项卡等...
所以现在我的 sharedInstance
看起来像这样:
static var sharedInstance: BannerViewManager {
struct Static {
static var onceToken: dispatch_once_t = 0
static var instance: BannerViewManager? = nil
}
dispatch_once(&Static.onceToken) {
Static.instance = BannerViewManager()
}
return Static.instance!
}
我想我明白问题出在哪里了。它与我初始化 BannerViewManager
class 的共享实例的方式无关。事实上,无论是使用 dispatch_once
还是新的 swift 2.0 方式,结果都给出了完全相同的行为。
导致 iAd 在调用 bannerViewDidLoadAd
时没有立即显示的原因是 viewDidLayoutSubviews
实际上从未被调用过!
我不得不到处添加一些打印语句。在我的代码和Apple示例代码中都得出了这个结论。
所以 setNeedsLayout
而不是 layoutIfNeeded
强制触发 viewDidLayoutSubviews
- 一般在bannerViewDidLoadAd中打断点,回调函数类似
- 检查你是否有像 swift 中那样的代理 class YourClassViewController: UIViewController, ADBannerViewDelegate.
- 检查你的情况,你说 "I have to either rotate the simulator or go to another tab so that it appears",所以可能是哪种方法造成的。我知道你已经猜到了。
- 阅读文档,分析。