2013-05-13 69 views
0

实施以下遇到问题:NSView Contraints - 如何强制子视图的纵横比保持不变?

+-------------------+ 
|     | 
|     | 
|  RESIZABLE  | 
|     | 
|  NSVIEW  | 
|     | 
|     | 
|     | 
|     | 
|     | 
|     | 
|     | 
|     | 
|     | 
|+-----------------+| 
||     || 
||  STATIC  || 
||     || 
||  SUBVIEW  || 
||     || 
|+-----------------+| 
+-------------------+ 

当子视图的纵横比必须保持恒定(如用户改变可调整大小的视图的宽度)。

我想使用约束做,到目前为止,我已经有了:

//This is a snippet of the resizable view class 

[self addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:subview attribute:NSLayoutAttributeWidth multiplier:1 constant:0]]; 
[self addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:subview attribute:NSLayoutAttributeBottom multiplier:1 constant:0]]; 

//This is a snippet of the subview class 

[self addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeWidth multiplier:aspectRatio constant:0]]; 

可调整大小的视图的框架初始设置。在这种情况下,不设置子视图的框架是有意义的?目前,主视图似乎消失了 - 它的宽度开始为零。

我应该如何解决这个问题 - 如果可能的话,我喜欢使用约束!

+0

我会认为你展示的前两个约束是背对背的;你不想让子视图受到父视图(可调整大小)的限制吗? – trojanfoe 2013-05-13 11:54:54

+0

@trojanfoe这就是我一开始想到的,但是这样做会产生一个错误:“无法在视图上安装约束,约束是否从视图的子树外引用某个东西?这是非法的。” – 2013-05-13 11:56:47

+0

嗯,我不是专家,但我知道你可以表达约束WRT的超视图,但你可能需要使用该方法的视觉语言版本。 – trojanfoe 2013-05-13 11:58:11

回答

3

这可以通过在IB中设置大部分约束,然后在代码中更改其中的一个来完成。静态子视图应该有任何想要调整大小的视图的边和底部的间距约束,以及固定的高度约束 - 在创建这些约束之后,如果有一个约束,您应该可以将约束删除到可调整大小的视图顶部。做一个IBOutlet的高度约束,并改变在这样的代码(heightCon是我的出路,而这个代码是在静态子视图子类):

- (void)awakeFromNib { 
    [self removeConstraint:self.heightCon]; 
    self.heightCon = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeWidth multiplier:.54 constant:0]; 
    [self addConstraint:self.heightCon]; 
} 

的0.54数量从我的高度的初始比例来到IB的宽度。

+0

是的,除了这可能应该在视图控制器的'-viewDidLoad'而不是应用程序委托。 – paulmelnikow 2013-05-13 16:06:03

+0

@noa,在OS X中没有viewDidLoad。 – rdelmar 2013-05-13 16:07:23

+0

在OS X的nib所有者的'-awakeFromNib'中。我通常设置一个标志以避免多次运行我的设置代码,因为在某些情况下,该方法被称为多于一旦。对于NSWindowController,你也可以使用'-windowControllerDidLoadNib'。 – paulmelnikow 2013-05-13 16:12:16