iOS中的ViewController部分视图在方向更改时变黑

3
当我在特定方向上加载视图控制器时更改其方向,屏幕底部的一部分会变成黑色。
复现步骤:
1. 在一个视图控制器中有一个tableview(我认为这不是必需的,可以是任何视图) 2. 在某个操作期间,推送一个也具有tableview(我认为这不是必需的,可以是任何视图)的新视图控制器 3. 从一种方向旋转屏幕到另一种方向(从纵向到横向或从横向到纵向)。现在您将能够看到黑暗部分。 4. 按返回按钮以弹出当前的视图控制器 5. 现在从一种方向旋转到另一种方向(从纵向到横向或从横向到纵向)。现在您也将能够在这里看到黑暗部分。
视图控制器的底部部分变成了黑色。
我能够复制7次中的10次。
FYI:
我的Viewcontroller只有tableview,所有单元格都有自动布局约束。尝试理解为什么会发生这种情况,并希望修复它。
有关复制问题的更多详细信息:
基本上,只有当您以倾斜的姿势持有设备并且要么推送或弹出视图控制器,而页面正在尝试加载时,您才能复制此问题,然后更改方向,那么问题就会发生。
换句话说,您必须像操纵方向盘一样倾斜设备。
只有在您将设备用作方向盘时才会出现这个问题:)

这个回答解决了你的问题吗?UIView在方向改变后没有更新frame - Ujesh
你能分享一些关于这个 UIViewController 的代码吗? - Suryakant Sharma
展示你的两个类代码并添加操作界面。 - Anbu.Karthik
@SuryakantSharma - 我的视图控制器只有一个表格视图,我所做的就是将一些本地数据加载到表格视图中。表格视图使用自动布局约束来扩展到整个视图控制器的屏幕上。无论是对于表格视图还是表格视图单元格,都没有自动布局问题。这个问题只会在上述情况下发生。 - dinesh R
@Anbu.Karthik - OP UI 是什么?这两个类都是视图控制器,只有一个表格视图用于整个屏幕。它们都使用本地数据来显示 UI 中的数据元素。 - dinesh R
显示剩余4条评论
5个回答

3

在你的 viewWillTransition 方法中调用 layoutIfNeeded()。


在 viewWillTransition 中尝试调用 setNeedsLayout(),然后调用 layoutIfNeeded()。 - Manish Malviya
将表格框架设置为固定值可以解决一个视图控制器(viewWillTransition)中的问题,谢谢。然而,在另一个视图控制器中它却不起作用,很奇怪。顺便说一下,setNeedsLayout是异步的,视图必须等待下一个UI更新周期,而layoutifneeded是同步的。但无论如何两者都不起作用。 - dinesh R

3

我也遇到了同样的问题。

我的视图控制器只有一个表格视图,当我们在推送或弹出导航时旋转屏幕,就会发生这种情况。

尝试在 viewDidLayoutSubviews 中设置框架。

   -(void)viewDidLayoutSubviews{
    CGRect screen = [[UIScreen mainScreen] bounds];
    CGFloat width = CGRectGetWidth(screen);
    CGFloat height = CGRectGetHeight(screen);
    CGRect frame = self.tableView.frame;
    // To check if there's any mismatch between the sizes of screen and tableview then set the tableview frame same as screen frame.
    if (CGRectGetHeight(frame) != height && CGRectGetWidth(frame) != width) {
        self.tableView.frame = CGRectMake(0, 0, width, height);
    }
}

或者尝试在 viewWillTransitionToSize 中设置框架

-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator{
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    CGRect screen = [[UIScreen mainScreen] bounds];
    CGFloat width = CGRectGetWidth(screen);
    CGFloat height = CGRectGetHeight(screen);
    CGRect frame = self.tableView.frame;
    if (CGRectGetHeight(frame) != height && CGRectGetWidth(frame) != width) {
        self.tableView.frame = CGRectMake(0, 0, width, height);
    }
}

注意:

如果设置表格视图的框架 self.tableView.frame = CGRectMake(0, 0, width, height); 不起作用,那么您可以尝试使用 [self.tableView layoutIfNeeded]


它在我的一个视图控制器中可以工作,但在另一个视图控制器中无法工作。 - dinesh R
很奇怪。你能在那个代码段中为tableview和屏幕的宽度和高度加入一些NSLog,看看发生了什么吗? - Durai Amuthan.H
我尝试在该区域周围放置日志。以下是我的发现:当这个问题出现在特定的视图控制器中时,既没有调用viewDidLayoutSubviews也没有调用viewWillLayoutSubviews。我在其他一些视图控制器中遇到了同样的页面暗问题。在那里,通过使用上面的代码片段解决了问题,并且布局子视图被调用,这就是问题得以解决的原因。我想知道为什么这些委托对于这个特定的视图控制器没有被调用? - dinesh R
尝试调用 viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator 并设置框架。 - Durai Amuthan.H

3

使用此方法尝试在旋转后重置TableView的布局:

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        tableView.layoutIfNeeded()
    }

或者

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        tableView.layoutIfNeeded()
    }

当问题出现时,它没有被调用。 - dinesh R
好的,您想允许哪个ViewController进行旋转? - Nikunj
视图控制器旋转没有问题,它可以旋转,但有时在方向变化期间页面底部会变暗,请查看重现步骤。我的问题是当出现这个问题时,viewDidLayoutSubviews和viewWillLayoutSubviews都没有被调用。 - dinesh R

2
viewDidLayoutSubviews
中重新设置框架。

当我使用自动布局时,为什么要担心框架(frame)? - dinesh R
1
@dineshR,在这里,你可以在转换之前获取框架大小。因此,你的视图不会更新。你需要在转换完成后获取框架大小。你也可以使用 "viewWillTransition" 方法来实现。 - Krupa Parsaniya
我可以激活自动布局来重新绘制,而不是设置框架吗? - dinesh R
2
如果自动布局重新绘制有效,那么很好,否则我们有这个选项。 - Krupa Parsaniya
你可以调用 layoutIfNeeded 看看是否有帮助。 - Durai Amuthan.H
显示剩余3条评论

1
在一个视图控制器中(父视图控制器,推出新的视图控制器),在 viewDidLayoutSubviews 中设置框架可以解决另一个视图控制器中(子视图控制器,即被推送的视图控制器)在 viewWillTransition 中设置框架可以解决问题 :) 但我仍然不知道为什么没有通用的解决方案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接