故事板ViewController UI Glitch

时间:2015-03-11 00:15:57

标签: objective-c uiviewcontroller uinavigationcontroller storyboard autolayout

我有一个应用程序,我使用了Storyboard和autolayout来布局。我使用UINavigationViewController在按钮推送上以编程方式在UIViewControllers之间进行转换。我使用XCode 6,最低iOS版本号为7.1(在iPhone 4s上测试)。

我想编写一个可扩展到所有屏幕尺寸(iPhone,iPad等)的通用界面。为了做到这一点,我使用了与屏幕大小成比例定义的UIViews来分隔视图(请参见图1):

Figure 1
图1 - 测试应用程序主页的屏幕截图

在如上所示的图1中,红色正方形是UIViews,它们与屏幕尺寸成比例地定义,用于"空间" "真实"视图(蓝色和灰色)。

不幸的是,我开始注意到当用户在UIViewControllers之间转换时,视图控制器中的视图会“调整大小”。 (转换后,视图会移动几个像素或调整几个像素)。在用户转换到适当的屏幕后,这会使整个界面的相当刺激的体验稍微改变。

我将项目剔除到产生调整大小效果所需的合理最小代码,希望有人可以帮助我(因为我不知所措)。

第一个视图控制器的Storyboard视图层次结构: View hierarchy for 1st View Controller

第一视图控制器的约束:
Constraints for 1st View Controller

第二视图控制器的设置:
Setup of second view controller

用于从第一个控制器转换到第二个控制器的代码(推送):

- (IBAction)transitionForward:(UIButton *)sender
{
    UIViewController *controller = [self.navigationController.storyboard instantiateViewControllerWithIdentifier:@"BackController"];
    [self.navigationController pushViewController:controller animated:YES];
}

用于从第二个控制器弹出到第一个控制器的代码:

- (IBAction)transitionBack:(UIButton *)sender
{
    [self.navigationController popViewControllerAnimated:YES];
}

如上所述,问题是界面在用户点击按钮触发推/弹后加载后,视图控制器加载后,界面似乎会略微调整大小/移动。这种效果相当刺耳,我真的很感激如何阻止它。

可以在Github找到演示此问题的简化项目。

如果我还能提供其他任何内容,请直接询问。感谢您的时间和帮助。


编辑: 经过进一步调查,看来视图控制器的viewDidLayoutSubviews方法在视图控制器转换时被调用两次(以防有人诊断问题)。

1 个答案:

答案 0 :(得分:1)

尝试使用此代码替换您的推送和弹出功能,并且知道您的要求是否符合要求。

- (IBAction)transitionBack:(UIButton *)sender
{
    CATransition *transition = [CATransition animation];
    transition.duration = 0.45;
    transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
    transition.type = kCATransitionFromLeft;
    [transition setType:kCATransitionPush];
    transition.subtype = kCATransitionFromLeft;
    transition.delegate = self;
    [self.navigationController.view.layer addAnimation:transition forKey:nil];


    [self.navigationController popViewControllerAnimated:NO];
}

- (IBAction)transitionForward:(UIButton *)sender
{

    UIViewController *controller = [self.navigationController.storyboard instantiateViewControllerWithIdentifier:@"BackController"];
    CATransition *transition = [CATransition animation];
    transition.duration = 0.45;
    transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
    transition.type = kCATransitionFromRight;
    [transition setType:kCATransitionPush];
    transition.subtype = kCATransitionFromRight;
    transition.delegate = self;
    [self.navigationController.view.layer addAnimation:transition forKey:nil];


    [self.navigationController pushViewController:controller animated:NO];
}