Ho realizzato la seguente app di esempio per illustrare la mia domanda.Come utilizzare l'autolayout con NSTableView basato su visualizzazione quando la visualizzazione viene fornita da un NSViewController?
La vista di sinistra è una vista segnaposto (aggiunta in Interface Builder). Quando l'app viene caricata, aggiungo una sottoview gestita da NSViewController. NSViewController disegna i diversi rettangoli colorati, ciascuno dei quali è un NSView, e il layout di queste viste colorate gestite da vincoli creati a livello di codice e aggiunti al metodo
-loadView
del controller.La vista di destra è una NSTableView (aggiunta in Interface Builder). Quando l'app viene caricata, utilizzo la stessa classe NSViewController per fornire viste per la vista tabella (viene aggiunta una sola riga).
Quando aggiungo la visualizzazione secondaria la vista posto titolare aggiungo anche due vincoli aggiuntivi,
[_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]];
Questi vincoli impostare il telaio della visualizzazione secondaria uguale ai limiti della superview. Va tutto bene.
Tuttavia, quando fornisco la vista per NSTableView utilizzando il metodo delegato -tableView:viewForTableColumn:row:
, la vista non è stata ancora aggiunta alla tabella. Come tale non ha una superview, quindi i vincoli non possono (ancora) essere aggiunti alla vista. Questo è il motivo per cui la vista nella vista tabella non ha gli stessi limiti della cella di visualizzazione tabella.
Quindi la mia domanda è: come posso aggiungere vincoli alla vista che fornisco alla vista tabella? Posso accedere nuovamente alla vista dopo che la vista tabella è stata aggiunta? Questo sembra un po 'hack-ish.
Il codice sorgente per l'AppDelegate.h,
#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
e 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
Aggiorna @jrturton
Aggiungendo i vincoli -(void) tableView:(NSTableView *)tableView didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row
ha funzionato.
@swalkner
I vincoli che ho aggiunto sono molto semplici,
-(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]];
}
come si presenta il tuo 'tableView: didAddRowView: forRow:'? Mi piacerebbe ottenere la stessa cosa ma non farlo funzionare ... – swalkner
Osservando lo speciale. Letteralmente basta applicare i vincoli alla vista (vedi sopra ho fatto una modifica per te). –