私の質問を説明するために、以下のサンプルアプリケーションを作成しました。ビューがNSViewControllerによって提供されるとき、ビューベースのNSTableViewでautolayoutを使用するには?
左図は、(Interface Builderで添加)プレースホルダ図です。アプリケーションがロードされると、NSViewControllerによって管理されるサブビューを追加します。 NSViewControllerは、それぞれがNSViewである異なる色の長方形を描画し、これらの色付きビューのレイアウトはプログラムで作成された制約によって管理され、コントローラの
-loadView
メソッドに追加されます。右のビューは、NSTableView(Interface Builderで追加)です。 Appがロードされると、同じNSViewControllerクラスを使用して、テーブルビューのビューを提供します(1つの行だけが追加されます)。
IがサブビューをIは、2つの追加の制約を追加するプレースホルダビューを追加し、
[_placeholderView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[CTRL_VIEW]|" options:0 metrics:nil views:views]];
[_placeholderView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[CTRL_VIEW]|" options:0 metrics:nil views:views]];
これらの制約は、スーパーの境界に等しくなるようにサブビューのフレームを設定します。すべてが良いです。
ただし、デリゲートメソッド-tableView:viewForTableColumn:row:
を使用してNSTableViewのビューを提供すると、そのビューはまだテーブルに追加されていません。そのため、スーパービューがないため、ビューに制約を追加することはできません。これは、テーブルビューのビューがテーブルビューセルと同じ境界を持たない理由です。
私の質問は、私がテーブルビューに提供するビューに制約を追加する方法です。テーブルビューを追加した後、ビューに再度アクセスできますか?これは少しハックされているようです。
AppDelegate.hのソースコード、
@jrturton
#import <Cocoa/Cocoa.h>
@class BlahViewController;
@interface AppDelegate : NSObject <NSApplicationDelegate, NSTableViewDataSource, NSTableViewDelegate>
@property (assign) IBOutlet NSWindow *window;
/* Left view controller and place holding view */
@property (strong) BlahViewController *viewController;
@property (weak) IBOutlet NSView *placeholderView;
/* Right view (which is an NSTableView) */
@property (weak) IBOutlet NSTableView *tableView;
@end
とAppDelegate.m、
#import "AppDelegate.h"
#import "BlahViewController.h"
@interface AppDelegate()
@property NSMutableArray *tableData;
@end
@implementation AppDelegate
- (id)init
{
self = [super init];
if (self) {
_tableData = [[NSMutableArray alloc] init];
[_tableData addObject:[[BlahViewController alloc] initWithNibName:@"BlahViewController" bundle:nil]];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints"];
}
return self;
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
/* Add a managed subview to the place holder view*/
_placeholderView.layer.backgroundColor = CGColorCreateGenericGray(0.5, 1.0);
_viewController = [[BlahViewController alloc] initWithNibName:@"BlahViewController" bundle:nil];
[_viewController.view setFrame:_placeholderView.bounds];
[_placeholderView addSubview:_viewController.view];
/* Additional constraints so the managed subview resizes with the place holder view */
NSDictionary *views = @{ @"CTRL_VIEW" : _viewController.view };
[_placeholderView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[CTRL_VIEW]|" options:0 metrics:nil views:views]];
[_placeholderView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[CTRL_VIEW]|" options:0 metrics:nil views:views]];
}
-(NSInteger) numberOfRowsInTableView:(NSTableView *)tableView
{
return [_tableData count];
}
-(id) tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
return [_tableData[row] view];
}
-(CGFloat) tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row {
return 150.;
}
@end
更新に制約を追加-(void) tableView:(NSTableView *)tableView didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row
が働いた。私は追加
@swalkner
制約が非常に基本的なもの、
-(void) tableView:(NSTableView *)tableView didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row {
NSView *view = [rowView viewAtColumn:0];
NSDictionary *views = NSDictionaryOfVariableBindings(view);
[view.superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-12-[view]-12-|" options:0 metrics:nil views:views]];
[view.superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-12-[view]-12-|" options:0 metrics:nil views:views]];
}
あなたの 'tableView:didAddRowView:forRow:'はどのように見えますか?私は同じことを達成したいと思いますが、それを働かせないでください。 – swalkner
注目に値する。文字通り、ビューに制約を適用します(上記の私は編集を行いました)。 –