【问题标题】:iOS 8 - Changing UIScrollView's frame with AutoLayout enablediOS 8 - 在启用自动布局的情况下更改 UIScrollView 的框架
【发布时间】:2014-11-21 18:41:41
【问题描述】:

我正在为 iOS 8 更新我的应用程序,并向我的所有视图添加 AutoLayout 约束。他们大部分时间都在工作,但UIScrollView (slideUpScrollView) 给我带来了一些麻烦。里面有一个UIButton (toggleDrawerButton) 来切换SV 的框架。在 IB 中,将 SV 保持在 50pts 的底部是有限制的。当 toggleButton 被按下时,它应该将 SV 的原点更改为视图的顶部,模拟抽屉效果。

开/关效果有问题。当我按下 toggleDrawerButton 时,它有时会产生我想要的效果,就像在 iOS 7 中一样(不调用 viewDidLayoutSubviews)。其他时候,在我的帧移动后调用 viewDidLayoutSubviews 时,SV 会产生奇怪的效果。然后 VDLS 将尝试重新约束 SV 并将 toggleDrawerButton 恢复到原来的关闭位置。当抽屉应该打开时,这会导致视图被放回底部。 VDLS 似乎在 toggleDrawerButton 按下时被随机调用。有时它会被调用,有时它不会。

如何正确重新定位 SV 的框架以使其向顶部移动,而无需自动布局重新约束它?另外,为什么有时仅在按下 toggleDrawerButton 时才调用 VDLS?行为不一致,因此更难找到解决方案。

这里是toggleDrawerButton的动作代码:

- (void) toggleAddEditDrawer {
if (self.drawerToggle == 0) { // Open the Drawer
    self.drawerToggle = 1;

    self.itemNameTextField.text = nil;
    self.quantityTextField.text = nil;

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.4];
    [UIView setAnimationDelay:0.0];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];

    //Rotate the button and make the SV frame slide up

    self.toggleDrawerButton.transform = CGAffineTransformMakeRotation(M_PI/4);
    self.slideUpScrollView.frame = CGRectMake(0, self.tableView.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
    self.slideUpScrollView.contentSize = self.slideUpScrollView.frame.size;


    [UIView commitAnimations];
    [self.itemNameTextField becomeFirstResponder];

    NSLog(@"OPEN Toggle - tableview location is: %@",NSStringFromCGRect(self.tableView.frame));
    NSLog(@"OPEN Toggle - scrollview location is: %@",NSStringFromCGRect(self.slideUpScrollView.frame));
    NSLog(@"OPEN Toggle - toggleButton location is: %@",NSStringFromCGRect(self.toggleDrawerButton.frame));


} else { //Close the Drawer
    self.drawerToggle = 0;
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.4];
    [UIView setAnimationDelay:0.0];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];

    //Reverse the rotation and  make the SV frame slide down
    self.toggleDrawerButton.transform = CGAffineTransformMakeRotation(0);
    self.slideUpScrollView.frame = CGRectMake(0, self.tableView.frame.origin.y + self.tableView.frame.size.height, self.view.frame.size.width, 50);
    self.slideUpScrollView.contentSize = self.slideUpScrollView.frame.size;

    [UIView commitAnimations];
    [self.view endEditing:YES];

    NSLog(@"CLOSE Toggle - tableview location is: %@",NSStringFromCGRect(self.tableView.frame));
    NSLog(@"CLOSE Toggle - scrollview location is: %@",NSStringFromCGRect(self.slideUpScrollView.frame));
    NSLog(@"CLOSE Toggle - toggleButton location is: %@",NSStringFromCGRect(self.toggleDrawerButton.frame));


}
NSLog(@"Drawer Posistion is: %d",self.drawerToggle);

}

编辑:这里有一些控制台日志。

工作帧动画日志:
OPEN 切换 - 表格视图位置是:{{0, 2}, {320, 452}}
打开切换 - 滚动视图位置是:{{0, 2}, {320, 504}}
打开切换 - 切换按钮位置是:{{128.88730162779191, -6.1126983722080901}, {62.225396744416173, 62.225396744416173}}
抽屉位置为:1

VDLS 帧重约束日志:
OPEN 切换 - 表格视图位置是:{{0, 2}, {320, 452}}
打开切换 - 滚动视图位置是:{{0, 2}, {320, 504}}
打开切换 - 切换按钮位置是:{{128.88730162779191, -6.1126983722080901}, {62.225396744416173, 62.225396744416173}}
抽屉位置:1
VDLS - 表视图位置是:{{0, 2}, {320, 452}}
VDLS - 滚动视图位置是:{{0, 454}, {320, 50}}
VDLS - 切换按钮位置是:{{128.88730162779191, -6.1126983722080901}, {62.225396744416173, 62.225396744416173}}

【问题讨论】:

  • 你解决了吗?

标签: ios objective-c uiscrollview autolayout


【解决方案1】:

通常在使用 AutoLayout 时,您不能手动操作视图的框架。您需要为约束更改而不是框架更改设置动画。

以下是有关为约束设置动画的信息: https://happyteamlabs.com/blog/ios-how-to-animate-autolayout-constraints/

在启用自动布局时设置框架的更多信息: Can I use setFrame and autolayout on the same view?

【讨论】:

  • 这让一切顺利进行。无需更改 ScrollView 的框架,我只需要在代码中编辑适当的约束常量即可重新定位它。
  • 仅供参考,链接已移至:happyteamlabs.com/blog/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-07
  • 1970-01-01
  • 1970-01-01
  • 2012-09-27
  • 1970-01-01
  • 1970-01-01
  • 2012-09-24
相关资源
最近更新 更多