Objective c 如果在viewDidLoad之外启用了横幅广告,则旋转后的布局不正确

Objective c 如果在viewDidLoad之外启用了横幅广告,则旋转后的布局不正确,objective-c,layout,ios8,iad,Objective C,Layout,Ios8,Iad,我在使用iOS 8应用程序时遇到问题。我的应用程序需要从网络服务器获取信息,以确定是否应该播放广告。这可能需要一段时间,因此viewDidLoad中的代码不会等待它,而是调用setcandisplaybanerads:NO。然后,一旦信息进入,setcandisplaybanerads:YES在viewDidLoad之外调用 我已确定需要在viewDidLoad内部调用setcandisplaybanerads:NO,否则setcandisplaybanerads:YES无法正确调用ads并生成

我在使用iOS 8应用程序时遇到问题。我的应用程序需要从网络服务器获取信息,以确定是否应该播放广告。这可能需要一段时间,因此
viewDidLoad
中的代码不会等待它,而是调用
setcandisplaybanerads:NO
。然后,一旦信息进入,
setcandisplaybanerads:YES
viewDidLoad
之外调用

我已确定需要在
viewDidLoad
内部调用
setcandisplaybanerads:NO
,否则
setcandisplaybanerads:YES
无法正确调用ads并生成大量内部异常

问题在于,一旦在
viewdidLoad
之外启用了广告,布局就会混乱。我在下面用两幅图片进行了说明。顶部的是“之前”,底部的是“之后”,就像在节目结束后点击广告一样

请注意,在“之前”图像中,显示广告和标签在旋转后都会出现在各自的角落中。在“后”图像中,横向方向不再正确。它只保留了一个标签和横幅广告

我已经向苹果提交了一份bug报告,并提供了一个可以在DropBox上访问的示例项目。请随意下载并试用

如果有人能提供一些见解,也许是一个解决方案,我不必改变逻辑顺序,即在
viewDidLoad
完成之前不显示广告,那将不胜感激


黑暗中的总镜头,但一旦广告出现,如果您调用setNeedsLayout或setneedsupdatecontraint(如果您使用的是自动布局,我假设您是),会发生什么情况?另外,确保在广告视图和其他视图之间正确设置了约束。这些可能不是正确的答案,但我希望它能为真正的问题/解决方案提供一些额外的见解。

将这两行放在
viewdiload:

[self setCanDisplayBannerAds:YES];
[self setCanDisplayBannerAds:NO];
第一个电话正确设置广告,第二个电话立即确保广告不会显示。稍后您可以调用
[self-setCanDisplayBannerAds:YES],它将毫无问题地处理方向更改。

老实说,至少在当前SDK中,它可能会工作。但感觉有点奇怪。这并不能真正解释为什么它会起作用

查看
setCanDisplayBannerAds:
的文档,我们看到:

请务必注意,这将通过在视图控制器的视图上方插入新的容器视图来修改视图控制器的视图层次结构。其影响是视图控制器的view属性将不再返回最初提供的视图,而是返回新的容器。要访问原始视图,请使用originalContentView属性

因此,它实际上替换了UIViewController的
.view
属性。记住这一点

当UIViewController显示在屏幕上时,它的大小将调整为适合整个屏幕(或至少适合它所占用的容器)。因此,UIViewController的
.view
属性获得了
UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth
,因此其高度和宽度是灵活的,并且可以拉伸以适合容器

当您调用
[self-setCanDisplayBannerAds:YES]时
viewDidLoad
中,UIViewController的
.view
属性将被替换为新的UIView,并且由于它位于
viewDidLoad
中,因此它的
自动重新设置任务
将被适当设置。相反,调用
[self-setCanDisplayBannerAds:NO]viewDidLoad
中的code>实际上什么都不做

在示例应用程序中,当您调用
[self-setCanDisplayBannerAds:YES]时
viewDidLoad
之外,我们可以看到
autoresizingMask
实际上没有设置为拉伸。这就是导致问题的原因:

- (IBAction)TouchUpInside:(id)sender {
    NSLog(@"Touch Up Inside");
    NSLog(@"Original View: %@", self.view);
    [self setCanDisplayBannerAds:YES];
    NSLog(@"New View: %@", self.view);
    NSLog(@"Content View: %@", self.originalContentView);
}

Output: 
2015-02-05 11:32:19.654 ID19658866[12404:3600041] Touch Up Inside
2015-02-05 11:32:19.655 ID19658866[12404:3600041] Original View: <UIView: 0x7f9c42717440; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x7f9c42717710>>
2015-02-05 11:32:19.666 ID19658866[12404:3600041] New View: <UIView: 0x7f9c42523fb0; frame = (0 0; 375 667); layer = <CALayer: 0x7f9c42524080>>
2015-02-05 11:32:19.666 ID19658866[12404:3600041] Content View: <UIView: 0x7f9c42717440; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x7f9c42717710>>
它会起作用,我们会知道原因


或者我们可以,你知道。。。只需调用
[self-setCanDisplayBannerAds:YES]替换我们的
self.view
属性即可
viewdiload
中,因此它会自动正确设置
自动重新设置任务。

坦率地说,Yimin Rong拥有所有可用任务中最好的。然而,如果这是一个溢价v。标准帐户类型的东西,如果您在本地存储一个变量,并让用户点击“恢复购买”按钮,这不是最好的吗。这样,即使用户离线,你也可以显示广告(如果它们存储在本地),当它们在线时,你可以从广告商那里获得利润。祝你申请好运

谢谢,您尝试了
setNeedsUpdateConstraints
setNeedsLayout
setNeedsDisplay
单独和组合使用-布局错误仍然存在。因为它涉及IAD,希望尽快得到苹果的回应。是的,我相信这不是解决方案,但希望你能看到一些东西,可能会对真正的问题/解决方案有更多的启发。无论你发现了什么,我希望你能回来,用你最终学到的东西更新你的帖子。谢谢,伙计。这可能是一个评论。将答案保存为答案,而不是猜测以抓住要点。谢谢。我认为大约在中间有一个拼写错误,以“在你的示例应用程序中,当你调用…”开头的段落,我认为应该是
[self-setCandisplaybanerads:YES]而不是
?啊,你是对的;固定的。关键是用
YES
调用它会改变视图层次结构,因此在
viewDidLoad
之外调用它并不能像应该的那样设置
autoresizingMask
。我注意到,如果我不在
viewDidLoad
中调用
setCanDisplayBannerAds:
,然后启用广告,那么
self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;