2

我正在寻找实现一个上拉菜单样式的界面。我希望菜单与父视图的大小相同,但最初定位为只有其顶部 65 个像素可见。轻按菜单将使其从底部开始覆盖大部分屏幕的屏幕动画。在不是实际菜单选项的任何地方进一步点击菜单会将其放回原来的位置。

我设法在没有约束的情况下实现了这一点,但出于好奇,我想我会尝试用约束来实现同样的事情(希望减少我在各种设备尺寸等上处理旋转的代码量)。

谁能告诉我视觉格式字符串与父级匹配大小,但将顶部链接到父级底部上方 65 像素?

另外,当我触摸菜单时,我将如何为帧位置的变化设置动画?

4

2 回答 2

4

我可能会建议两种方法:

  1. 与其将其设置为全尺寸且大部分不在屏幕上,不如将其设置为 65 像素并限制在底部:

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[menuview]|" options:0 metrics:nil views:views]];
    self.verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[menuview(65)]|" options:0 metrics:nil views:views];
    [self.view addConstraints:self.verticalConstraints];
    

    这样,当你改变方向时,它会一直固定在底部,65 点高。

    然后,当您想要将其设置为动画时,您可以:

    [self.view removeConstraints:self.verticalConstraints];
    self.verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[menuview]|" options:0 metrics:nil views:views];
    [self.view addConstraints:self.verticalConstraints];
    [UIView animateWithDuration:0.25 animations:^{
        [self.view layoutIfNeeded];
    }];
    
  2. 另一种方法,使其全尺寸和大部分离屏要求您至少使用一个非 VFL 约束。同样,您定义初始约束,这次将其定义为主视图(其父视图)的高度,但菜单的顶部约束是距其父视图的底部约束 -65 点(这是最后一个约束这不能在 VFL 中完成)。注意,因为我想引用 VFL 中的超级视图(定义高度相等),所以我将使用一个临时变量,mainview

    UIView *mainview = self.view;
    NSDictionary *views = NSDictionaryOfVariableBindings(menuview, mainview);
    [mainview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[menuview]|" options:0 metrics:nil views:views]];
    [mainview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[menuview(==mainview)]" options:0 metrics:nil views:views]];
    self.verticalConstraint = [NSLayoutConstraint constraintWithItem:menuview attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:mainview attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-65.0];
    [mainview addConstraint:self.verticalConstraint];
    

    然后当你想把它动画到位时,你摆脱那个垂直约束,并创建一个新的约束,将菜单视图的顶部约束到其父视图的顶部:

    [mainview removeConstraint:self.verticalConstraint];
    self.verticalConstraint = [NSLayoutConstraint constraintWithItem:menuview attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:mainview attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0];
    [mainview addConstraint:self.verticalConstraint];
    [UIView animateWithDuration:0.25 animations:^{
        [mainview layoutIfNeeded];
    }];
    

其他技术(例如将顶部约束设置为等于视图高度减去 65 点)需要您在旋转事件期间进行调解。上述两种技术不需要。

于 2013-08-20T14:14:24.060 回答
1

这是Apple 关于表达约束的文档

您需要两个重要的垂直约束。首先是子视图的高度应该等于父视图的高度。二是子视图的顶部应该与父视图的底部有一定的距离。

如果您跟踪属性中的第二个约束,动画将变得非常容易。您可以将约束替换为另一个约束或编辑其constant属性,以便子视图的顶部与父视图的顶部对齐。如果你把它放在一个动画块中并跟随它

[parent layoutIfNeeded];

约束更改将动画。

希望这可以帮助!

于 2013-08-20T14:20:41.263 回答