我在使用Cocoa Autolayout时遇到了一些问题。
我有一个窗口,我(以编程方式)添加了一个NSTableView(及其NSScrollView)。到现在为止一切正常。我可以调整窗口大小,表格也可以正确调整大小。
这是我使用的代码。

MyListViewController *viewController = [[MyListViewController alloc] initWithNibName:@"ListView" bundle:nil];

[self.mainContentView addSubview:viewController.view];
[viewController.view setTranslatesAutoresizingMaskIntoConstraints:NO];

[self.mainContentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[insertedView]|"
                                                                                 options:0
                                                                                 metrics:nil
                                                                                   views:@{@"insertedView" :viewController.view}]];
NSArray *verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[insertedView]|"
                                                                           options:0
                                                                           metrics:nil
                                                                             views:@{@"insertedView" :viewController.view}];

[self.mainContentView addConstraints:verticalConstraints];


现在,我想在运行时添加(和删除)位于表顶部的另一个视图。
该视图是具有NSPredicateEditorNSScrollView。明确说明:当您在搜索字段中键入内容,并且带有可能的搜索选项的视图出现在主窗口中时,我正在尝试实现与Finder相同的行为。

我这样处理:

AdvancedFilterViewController *viewController = [[AdvancedFilterViewController alloc] initWithNibName:@"AdvancedFilterView" bundle:nil];

[self.mainContentView addSubview:viewController.view];
[viewController.view setTranslatesAutoresizingMaskIntoConstraints:NO];

[self.mainContentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[insertedView]|"
                                                                             options:0
                                                                             metrics:nil
                                                                               views:@{@"insertedView" :viewController.view}]];
[self.mainContentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[insertedView(<=225)][prevView]|" // >= size of one row, <= size of 8 + 1 rows
                                                                             options:0
                                                                             metrics:nil
                                                                               views:@{@"insertedView" :viewController.view, @"prevView" : self.listView.view}]];


我希望至少有一行谓词(25分)可见。当用户按下加号按钮时,就会出现更多视图(滚动视图应适应其大小)。经过几行(我决定为9)后,滚动条应开始出现,并且窗口中的主视图应停止缩小。

问题是,当我插入过滤器视图时,它的大小几乎为零(例如1点)。或者,如果我添加最小点数为25点,则视图是可见的,但添加行只会增加滚动视图的“内部大小”,因此会出现滚动条(但滚动视图不会增长并且不会使列表视图缩小) 。

我希望我能正确解释问题。

编辑:

从答案中得到启发,我实现了代表:

- (void)ruleEditorRowsDidChange:(NSNotification *)notification
{
    //handle resizing of the view
    [self.predicateEditorHeight setConstant:[self.predicateEditor numberOfRows] * self.predicateEditor.rowHeight];
}


其中,self.predicateEditorHeight是对IBOutlet高度的约束的NSScrollView
然后在封闭的NSWindowController中,当我添加谓词编辑器视图时,我还添加了对NSTableView相对于谓词视图的比例的约束。
通过这种方式(因为我将其设置为0.3),滚动视图可以增长到某个点,然后,此后必须使用其滚动条。

关于约束,我仍然有一些问题:
例如,当我在编辑器中添加太多行时,我得到

2014-04-26 09:38:27.769 MyApp[2531:303] Unable to simultaneously satisfy constraints:
(
    "<NSLayoutConstraint:0x60000029dc40 V:[NSView:0x60000013fb80]-(0)-|   (Names: '|':NSView:0x60000013e500 )>",
    "<NSLayoutConstraint:0x60000029dbf0 V:[NSView:0x600000320b40]-(0)-[NSView:0x60000013fb80]>",
    "<NSLayoutConstraint:0x60000029dc90 NSView:0x60000013fb80.height >= 0.3*NSView:0x600000320b40.height>",
    "<NSAutoresizingMaskLayoutConstraint:0x608000288b60 h=--& v=--& V:[NSView:0x60000013e500(360)]>",
    "<NSLayoutConstraint:0x60000029dba0 V:|-(0)-[NSView:0x600000320b40]   (Names: '|':NSView:0x60000013e500 )>",
    "<NSLayoutConstraint:0x60000029d1a0 V:[NSView:0x600000320f00(275)]>",
    "<NSLayoutConstraint:0x60000029d420 V:[NSView:0x600000320f00]-(0)-|   (Names: '|':NSView:0x600000320b40 )>",
    "<NSLayoutConstraint:0x60000029d510 V:[NSView:0x600000320dc0]-(0)-[NSView:0x600000320f00]>",
    "<NSLayoutConstraint:0x60000029d330 V:|-(0)-[NSView:0x600000320dc0]   (Names: '|':NSView:0x600000320b40 )>",
    "<NSLayoutConstraint:0x60000029d060 V:[NSButton:0x6000001569a0'Search']-(4)-|   (Names: '|':NSView:0x600000320dc0 )>",
    "<NSLayoutConstraint:0x60000029d0b0 V:|-(5)-[NSButton:0x6000001569a0'Search']   (Names: '|':NSView:0x600000320dc0 )>"
)

Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x60000029d060 V:[NSButton:0x6000001569a0'Search']-(4)-|   (Names: '|':NSView:0x600000320dc0 )>

2014-04-26 09:38:27.770 MyApp[2531:303] Unable to simultaneously satisfy constraints:
(
    "<NSLayoutConstraint:0x60000029dc40 V:[NSView:0x60000013fb80]-(0)-|   (Names: '|':NSView:0x60000013e500 )>",
    "<NSLayoutConstraint:0x60000029dbf0 V:[NSView:0x600000320b40]-(0)-[NSView:0x60000013fb80]>",
    "<NSLayoutConstraint:0x60000029dc90 NSView:0x60000013fb80.height >= 0.3*NSView:0x600000320b40.height>",
    "<NSAutoresizingMaskLayoutConstraint:0x608000288b60 h=--& v=--& V:[NSView:0x60000013e500(360)]>",
    "<NSLayoutConstraint:0x60000029dba0 V:|-(0)-[NSView:0x600000320b40]   (Names: '|':NSView:0x60000013e500 )>",
    "<NSLayoutConstraint:0x60000029d1a0 V:[NSView:0x600000320f00(275)]>",
    "<NSLayoutConstraint:0x60000029d420 V:[NSView:0x600000320f00]-(0)-|   (Names: '|':NSView:0x600000320b40 )>",
    "<NSLayoutConstraint:0x60000029d510 V:[NSView:0x600000320dc0]-(0)-[NSView:0x600000320f00]>",
    "<NSLayoutConstraint:0x60000029d330 V:|-(0)-[NSView:0x600000320dc0]   (Names: '|':NSView:0x600000320b40 )>",
    "<NSLayoutConstraint:0x60000029d100 V:|-(4)-[NSButton:0x6000001564d0]   (Names: '|':NSView:0x600000320dc0 )>",
    "<NSLayoutConstraint:0x60000029d150 V:[NSButton:0x6000001564d0]-(5)-|   (Names: '|':NSView:0x600000320dc0 )>"
)

Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x60000029d150 V:[NSButton:0x6000001564d0]-(5)-|   (Names: '|':NSView:0x600000320dc0 )>

2014-04-26 09:38:27.775 MyApp[2531:303] Unable to simultaneously satisfy constraints:
(
    "<NSLayoutConstraint:0x60000029cf70 V:[NSTextField:0x600000198940]-(4)-|   (Names: '|':NSView:0x600000320dc0 )>",
    "<NSLayoutConstraint:0x60000029cfc0 V:|-(4)-[NSTextField:0x600000198940]   (Names: '|':NSView:0x600000320dc0 )>",
    "<NSLayoutConstraint:0x60000029dc40 V:[NSView:0x60000013fb80]-(0)-|   (Names: '|':NSView:0x60000013e500 )>",
    "<NSLayoutConstraint:0x60000029dbf0 V:[NSView:0x600000320b40]-(0)-[NSView:0x60000013fb80]>",
    "<NSLayoutConstraint:0x60000029dc90 NSView:0x60000013fb80.height >= 0.3*NSView:0x600000320b40.height>",
    "<NSAutoresizingMaskLayoutConstraint:0x608000288b60 h=--& v=--& V:[NSView:0x60000013e500(360)]>",
    "<NSLayoutConstraint:0x60000029dba0 V:|-(0)-[NSView:0x600000320b40]   (Names: '|':NSView:0x60000013e500 )>",
    "<NSLayoutConstraint:0x60000029d1a0 V:[NSView:0x600000320f00(275)]>",
    "<NSLayoutConstraint:0x60000029d420 V:[NSView:0x600000320f00]-(0)-|   (Names: '|':NSView:0x600000320b40 )>",
    "<NSLayoutConstraint:0x60000029d510 V:[NSView:0x600000320dc0]-(0)-[NSView:0x600000320f00]>",
    "<NSLayoutConstraint:0x60000029d330 V:|-(0)-[NSView:0x600000320dc0]   (Names: '|':NSView:0x600000320b40 )>"
)

Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x60000029cf70 V:[NSTextField:0x600000198940]-(4)-|   (Names: '|':NSView:0x600000320dc0 )>

最佳答案

您必须“通知”父视图,内部视图将调整大小。我的方法是观察谓词由其代表增长和收缩:

- (void)ruleEditorRowsDidChange:(NSNotification *)notification{

  NSInteger newRowCount = [_predicateEditor numberOfRows];
  NSInteger rowHeight = [_predicateEditor rowHeight];

  // Send a notification - size changes
  NSRect newFrame = self.view.frame;
  newFrame.size.height = 30 + newRowCount*rowHeight;
  [[NSNotificationCenter defaultCenter]postNotificationName:@"RowsDidChange" object:[NSValue valueWithRect:newFrame]];
  [[_heightConstraint animator] setConstant:rowHeight*newRowCount];
}


在父级ViewController中有一个“观察者”来观察大小变化:

 [[NSNotificationCenter defaultCenter]addObserverForName:@"RowsDidChange"
    object:nil
    queue:nil
    usingBlock:^(NSNotification * notification){
        NSValue *value =  (NSValue*)notification.object;
        NSRect rectValue = [value rectValue];

        NSRect newContentRect = self.resultsView.frame;
        newContentRect.size.height = self.resultsView.frame.size.height - rectValue.size.height;
        newContentRect.size.width = self.resultsView.frame.size.width;

        // Set new height to the mainViewController
        [[self.mainViewController view] setFrame:newContentRect];
}];


您不需要发送通知,也可以向您的父级viewcontroller发送一些委托方法。

祝好运。

关于macos - cocoa 自动布局:在运行时以编程方式插入(和删除) View ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22966386/

10-12 05:20