当我们在运行时更改模拟器方向时,UIViews 重叠

Posted

技术标签:

【中文标题】当我们在运行时更改模拟器方向时,UIViews 重叠【英文标题】:UIViews are overlapping when we change simulator orientation at run time 【发布时间】:2015-12-19 10:44:32 【问题描述】:

在我的项目中,我使用自动布局以编程方式添加了两个 UIViews

使用UIView 动画,当我单击下方屏幕中的 secondView 按钮时,我将第一个 UIView 推到 secondView UIView,当我单击 firstView 按钮时,我从第二个 UIView 推回第一个 UIView

我的问题是,当我在运行时更改模拟器方向时,第二个UIView 与第一个UIView 重叠。请帮忙解释为什么会出现这个问题。

我知道这是一个约束问题,但我们如何解决这个问题?

我的代码:-

#import "ViewController444.h"

@interface ViewController444 ()

    UIView * firstView;
    UIView * secondView;


@end

@implementation ViewController444
@synthesize DetailsView;

- (void)viewDidLoad 
    [super viewDidLoad];

    self.view.translatesAutoresizingMaskIntoConstraints = NO;

    firstView = [[UIView alloc] init];
    firstView.backgroundColor = [UIColor lightGrayColor];
    firstView.translatesAutoresizingMaskIntoConstraints = NO;
    [DetailsView addSubview:firstView];

    secondView = [[UIView alloc] init];
    secondView.backgroundColor = [UIColor orangeColor];
    secondView.translatesAutoresizingMaskIntoConstraints = NO;
    [DetailsView addSubview:secondView];

    NSDictionary *views = NSDictionaryOfVariableBindings(firstView,secondView);

    [DetailsView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[firstView]-0-|" options:0 metrics:nil views:views]];
    [DetailsView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[firstView]-0-|" options:0 metrics:nil views:views]];

    [DetailsView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[secondView]-0-|" options:0 metrics:nil views:views]];
    [DetailsView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[secondView]-0-|" options:0 metrics:nil views:views]];

    secondView.hidden = YES;



- (IBAction)firstViewAction:(id)sender 

    secondView.hidden = NO;

    secondView.frame=CGRectMake(firstView.frame.size.width+20, 0, firstView.frame.size.width, firstView.frame.size.height); // starting visible position

    [UIView animateWithDuration:0.5f
                          delay:0.0f
                        options:UIViewAnimationOptionBeginFromCurrentState
                     animations:^
                         [secondView setFrame:CGRectMake(0, 0, firstView.frame.size.width, firstView.frame.size.height)];  // final visible position
                     
                     completion:nil];


- (IBAction)secondViewAction:(id)sender 

    secondView.frame=CGRectMake(0, 0, firstView.frame.size.width, firstView.frame.size.height); // starting visible position

    [UIView animateWithDuration:0.5f
                          delay:0.0f
                        options:UIViewAnimationOptionBeginFromCurrentState
                     animations:^
                         [secondView setFrame:CGRectMake(firstView.frame.size.width+20, 0, firstView.frame.size.width, firstView.frame.size.height)];   // final visible position
                     
                     completion:nil];

@end

【问题讨论】:

【参考方案1】:

您的问题是因为您尝试以两种不同的方式进行布局,这通常(嗯,总是!)是个坏主意。您有一些 Auto Layout 代码,这非常棒,而且绝对是正确的解决方案,但是您正在以编程方式尝试计算和设置视图的框架,这 不能很好地与 Auto Layout 配合使用。

您的解决方案是修改动画中的约束,以便自动布局始终完全控制它们。您可以创建新的约束来反映您的新位置(如果您尝试更改 multiplier 值,则需要)或仅调整您现在拥有的值。

您可能有兴趣知道您可以添加竞争的自动布局约束集,然后仅为特定布局启用您想要的约束。您还可以考虑将您的 UI 移动到情节提要,在那里创建约束,然后为这些约束创建 IBOutlets,以便您可以在代码中操作它们。

【讨论】:

你能通过一些代码告诉我吗,因为我对这项技术很陌生 我确实尝试过提供一些特定的代码,但只有一小部分项目非常困难。简而言之,设置您需要能够重现程序的所有状态的所有约束,然后根据当前情况启用/禁用它们。如果您可以为一组约束设置动画(只需直接更改它们的 constant 值),您会发现这要容易得多。 你的意思是当改变方向时我必须“清除”和“添加”约束吗? 同样,您可以选择:1) 删除约束并重新添加,2) 使用竞争约束并启用/禁用,3) 使用一组约束并更改其常量。 请提供一些代码如何做到这一点,我真的不明白,而且我对这项技术很陌生

以上是关于当我们在运行时更改模拟器方向时,UIViews 重叠的主要内容,如果未能解决你的问题,请参考以下文章

在 SwiftUI 中更改方向时更新 UI

当设备方向改变时导致子视图重绘的正确方法是啥?

当屏幕在同一个视图控制器中旋转时替换 UIViews

更改方向时正确查看绘图,但在第一次显示时失败

当我结合 UIPanGestureRecognizer 和自动布局时,我的 UIViews 搞砸了

在应用程序启动时在后台加载 UIViews