【问题标题】:Resizing views that were designed with constraints调整使用约束设计的视图的大小
【发布时间】:2013-05-30 11:25:39
【问题描述】:
我有一个NSView xib,其中包含一个NSTextField 和一个自定义NSView。我使用了约束,这样当父视图调整大小时,子视图也会这样做。到现在为止还挺好。在命令期间,用户可以显示第三个子对象,这意味着我需要将其他两个视图向下移动,以适应它。这在我的动画中效果很好(我使用的是NSAnimationContext),但是在视图被调整大小,孩子们都根据约束快速回到他们的位置,忽略我已经改变了frame.origin.y 或frame.size.height 值的事实。
如何设计一个允许使用约束的用户界面,同时又允许我以编程方式调整 UI 元素的相对位置?
【问题讨论】:
标签:
objective-c
cocoa
user-interface
interface-builder
constraints
【解决方案1】:
如果您对子视图使用约束,那么您就是说您将这些视图的位置和大小委托给运行时。如果您尝试以编程方式更改这些值,您可能会认为事情会中断。
所以你需要做的是改变约束,而不是改变那些值。
当您更改约束以匹配您添加的新视图,然后为新位置设置动画时,请执行以下操作:
[UIView animateWithDuration:duration animations:^{[containingView layoutIfNeeded];}];
【解决方案2】:
您可以针对某些约束创建 IBOutlets。因此,您可以调整它们的常量(您可以在约束中更改的唯一内容)或通过删除旧约束并添加新约束来重新布局您的视图。
【解决方案3】:
按照 silvansky 的回答,我解决了以下问题:
const NSInteger offset = _textField.frame.size.height + 8;
NSRect newGridFrame = _grid.frame;
newGridFrame.size.height += show ? -offset : offset;
[NSAnimationContext beginGrouping];
[NSAnimationContext currentContext].completionHandler = ^(void)
{
_gridTopSpaceConstraint.constant += show ? offset : -offset;
_textField.hidden = !show;
_showingAddCategoryTextField = show;
};
[_grid.animator setFrame:newGridFrame];
[NSAnimationContext endGrouping];
我无法让[NSLayoutConstraint constant] 属性直接设置动画,因此必须通过设置帧动画来实现,然后在动画完成后更改约束。