【问题标题】:Moving views with constraints移动带有约束的视图
【发布时间】:2015-02-09 10:01:13
【问题描述】:

我的视图控制器中有几个视图在检测到向上滑动时向上移动,然后在检测到向下滑动时向下移动。我通过使用 CGRectOffset 调整 y 原点来强制视图移动。我现在已经使用 IB 对我的视图应用了约束,但我不确定移动视图的最佳方式是什么,以便它们最终位于 iphone 5、6 和 6+ 上的正确位置。

目前我正在做这样的事情:

[self.view layoutIfNeeded];

    self.panFrameVerticalConstraint.constant = self.panFrameVerticalConstraint.constant +338;

    [UIView animateWithDuration:5
                     animations:^{
                         [self.view layoutIfNeeded];
                     }];

使用比率更改常数会更好吗?那么对于上面的约束,与其使用 338,不如这样做:

    self.panFrameVerticalConstraint.constant = self.panFrameVerticalConstraint.constant + (self.panView.frame.size.height/1.680);

    //self.panView.frame.size.height = 568
    //(568/1.680) = 338

【问题讨论】:

  • @Brosef,请问您是如何实现向上/向下滑动手势来移动视图的?我正在尝试做类似的事情,但不知道从哪里开始。谢谢
  • @Pangu 我几乎按照以下答案中的步骤进行操作。我创建了一个IBOutlet NSLayoutConstraint 属性并将其连接到我想在界面生成器中调整的约束。然后,当我需要向上移动视图时,我像这样self.panFrameVerticalConstraint.constant = -(self.panedView.frame.size.height/1.68); 更改了我的常量。在更改常量之前,我调用了layoutIfNeeded。更改常量后,我在块中调用animateWithDuration 并再次调用layoutIfNeeded,就像下面的答案一样。
  • @Brosef,我很抱歉我还在学习,但是你是如何从 UIView 中检测到你想要向上移动以调用动画的向上滑动手势的?
  • @pangu 在viewDidLoad 中,您需要添加UISwipeGestureRecognizer 以及检测到滑动时调用的方法。 UISwipeGestureRecognizer * swipeUpRec = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleUpSwipe:)]; 然后将手势识别器添加到任何帧以检测滑动[self.someView addGestureRecognizer:swipeUpRec];

标签: ios objective-c swift autolayout nslayoutconstraint


【解决方案1】:

是的,更改常量时没有问题。这里的问题是你必须适当地设置你的约束。

我们来看一个例子。

我在 Storyboard 中有一个 UIView,我想更改它的宽度。它的默认宽度是1024

在一些动画之后,我们将其宽度更改为900

请按照以下步骤实现:

  1. 选择我们要在其中更新约束的UIView。这里我们需要更新width,所以我们会为宽度添加一个约束。

  1. 现在我们可以看到添加到 UIView 的新约束。

  1. 单击该约束。它将显示约束属性。现在我们想将宽度从 1024 减小到 900,以便在约束属性中将 Relation 属性更改为 Less Than or Equal。同样,如果您想从 1024 增加宽度,则 Relation大于或等于

  1. 现在为NSLayoutConstraint 创建一个IBOutlet 变量并将其与上述宽度约束连接起来。

  2. 改变宽度常数

Swift 5.0

@IBOutlet weak var viewWidthConstraint : NSLayoutConstraint!

func reduceWidth() {
    // Reduce width of view.
    UIView.animate(withDuration: 0.35, animations: { () -> Void in
        self.viewWidthConstraint.constant = 900
        self.view.layoutIfNeeded()
    })
}

func normalWidth() {
    // Change to the default width of view.
    UIView.animate(withDuration: 0.35, animations: { () -> Void in
        self.viewWidthConstraint.constant = 1024
        self.view.layoutIfNeeded()
    })
}

目标 C

@property (weak, nonatomic) IBOutlet NSLayoutConstraint     *viewWidthConstraint; 

- (void) reduceWidth {
    // Reduce width of view.
    [UIView animateWithDuration:0.35f animations:^{
        self.viewWidthConstraint.constant = 900;
        [self.view layoutIfNeeded];
    }];
}

- (void) normalWidth {
    // Change to default width of view.
    [UIView animateWithDuration:0.35f animations:^{
        self.viewWidthConstraint.constant = 1024;
        [self.view layoutIfNeeded];
    }];
}

【讨论】:

  • 这很有帮助。你说要让宽度从1024变成900,可是为什么要把约束常数改成705呢?
  • 这只是一个例子。在代码中,我需要将宽度减小到 705。
  • 很好的解释。我很感激。 +1
  • 伟大而正确的答案。我只想补充一点,设置约束不需要在UIView.animateWithDuration 块内完成。您可以在动画块之前设置约束,只需在块内调用layoutIfNeeded
  • 有人如何捕捉约束变化?我的意思是,宽度约束正在从 1024 更改为 900,反之亦然。如果我想捕捉约束等于 1000 的时刻怎么办?
猜你喜欢
  • 2020-06-23
  • 2018-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-22
  • 2021-04-18
相关资源
最近更新 更多