2015-07-04 7 views
7

Ho un progetto di esempio che illustra il problema quiCome aggiungere vincoli dopo un addSubview quindi la visualizzazione secondaria ridimensiona con il superview

https://github.com/ericgorr/autolayout_with_addsubview.git

ho una vista chiamata CalcView che voglio aggiungere a livello di codice come visualizzazione secondaria di una vista sulla finestra principale dell'app. Quando ridimensiono la finestra, , desidero ridimensionare CalcView.

In windowDidLoad in MainWindowController, aggiungo la visualizzazione secondaria facendo:

let calcViewController = ELIZCalcView() 
let calcView   = calcViewController.view 

calcContentView?.addSubview(calcViewController.view) 

cerco di aggiungere i vincoli facendo:

let bindings   = [ "calcView": calcView ] 

let horizontalContraint:[AnyObject] = NSLayoutConstraint.constraintsWithVisualFormat("H:|[calcView]|", options: NSLayoutFormatOptions(0), metrics: nil, views: bindings) 
let verticalContraint:[AnyObject] = NSLayoutConstraint.constraintsWithVisualFormat("V:|[calcView]|", options: NSLayoutFormatOptions(0), metrics: nil, views: bindings) 

calcContentView?.addConstraints(horizontalContraint) 
calcContentView?.addConstraints(verticalContraint) 

Ora, per qualcuno che sa interpretare correttamente che codice, è probabilmente molto evidente che non funzionerà. Dopo aver eseguito la mia app, non riesco a ridimensionare la finestra. Inoltre, vedo il seguente messaggio di errore nella console:

2015-07-04 16:04:45.019 aocsCalc[5797:3526462] Unable to simultaneously satisfy constraints: (
    "<NSLayoutConstraint:0x618000082440 V:|-(0)-[NSView:0x600000120f00] (Names: '|':aocsCalc.ELIZHighlightView:0x608000120500)>", 
    "<NSAutoresizingMaskLayoutConstraint:0x618000084100 h=--& v=&-- V:|-(-2)-[NSView:0x600000120f00] (Names: '|':aocsCalc.ELIZHighlightView:0x608000120500)>") 

Will attempt to recover by breaking constraint <NSLayoutConstraint:0x618000082440 V:|-(0)-[NSView:0x600000120f00] (Names: '|':aocsCalc.ELIZHighlightView:0x608000120500)> 

Set the NSUserDefault NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints to YES to have -[NSWindow visualizeConstraints:] automatically called when this happens. And/or, break on objc_exception_throw to catch this in the debugger. 

Se rimuovo il vincolo verticale, il messaggio di errore se ne va e posso ridimensionare la finestra in senso verticale.

Quindi, che cosa è necessario fare in modo semplice CalcView viene ridimensionato insieme alla finestra?

risposta

12

Prima di aggiungere il tuo calcView come visualizzazione secondaria provare a inserire questa riga di codice:

calcView.translatesAutoresizingMaskIntoConstraints = false 

Questo dovrebbe risolvere il problema.

Per impostazione predefinita su UIView/NSView questa proprietà è impostata su YES/true e crea il proprio set di vincoli in base alla maschera di autoresizing. Questi vincoli creati automaticamente sono in conflitto con quelli che hai creato nel codice.

Lo dice chiaramente anche nella descrizione dell'errore. Sulle righe 2 e 3 mostra che c'è 2 serie di vincoli verticali riguardanti una vista - NSView:0x600000120f00, che sembra essere il tuo calcView.

<NSLayoutConstraint:0x618000082440 V:|-(0)-[NSView:0x600000120f00] 
<NSAutoresizingMaskLayoutConstraint:0x618000084100 h=--& v=&-- V:|-(-2)-[NSView:0x600000120f00] 

Sono entrambi verticali. Il primo vuole aprire la vista al top della superview senza margini. Il secondo (creato automaticamente) vuole lo snap con un piccolo margine, presumibilmente preso da come è disposto in Interface Builder.

UPDATE

Creare un nuovo progetto di cacao applicazione e incollare il seguente codice:

override func viewDidLoad() { 
    super.viewDidLoad() 

    let view = NSView() 
    view.translatesAutoresizingMaskIntoConstraints = false 
    self.view.addSubview(view) 

    //Making it red just to see a little better. Ignore this two lines. 
    view.wantsLayer = true 
    view.layer?.backgroundColor = CGColorCreateGenericRGB(1, 0, 0, 1) 
    //----------------------------------------------------------------- 

    let views = ["view" : view] 
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("|-[view]-|", options: NSLayoutFormatOptions(0), metrics: nil, views: views)) 
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[view]-|", options: nil, metrics: nil, views: views)) 

} 

appena creato NSView è scattato alla vista controllori vista principale con margini standard (8 punti, è descritto come "-" nella stringa del formato visivo) e sta ridimensionando con la vista principale (vedi immagini). Un piccolo consiglio: non è necessario specificare "H:" nel formato visivo, solo "V:". È orizzontale per impostazione predefinita.

Questo dovrebbe darvi un'idea di come l'aggiunta di vincoli funzioni a livello di codice. Il codice potrebbe non essere ottimale, codice in Obj-C e conosco molto poco Swift.

Ho scaricato il tuo progetto. L'errore probabilmente si trova da qualche parte nella complicata gerarchia delle viste e nella manipolazione degli xib. Ma questa è tutta un'altra storia. State anche attenti con le visualizzazioni di scorrimento, sono un po 'complicate quando si parla di autolayout, su SO si può trovare molta copertura. Felice di codifica :)

enter image description here enter image description here

+0

Sono non hanno molta esperienza con lo sviluppo di OS X, ma penso che UIView e NSView agiscono lo stesso quando si tratta di vincoli. [Docs] (https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSView_Class/index.html#//apple_ref/occ/instp/NSView/translatesAutoresizingMaskIntoConstraints) dice che NSView ha quella proprietà. Devi averlo sbagliato o qualcosa di simile. – NKorotkov

+0

Cambiarlo da una chiamata di funzione a un assegnazione di proprietà ha eliminato l'errore di compilazione, ma il comportamento effettivo che sto vedendo è molto peggiore. Le viste non sono più posizionate correttamente sulla finestra. Ho aggiornato il progetto git hub con la modifica. – ericg

+0

Alla tua domanda originale è stata data una risposta, quindi dovresti considerare di dare a NKorotkov il merito. Ho scaricato ed eseguito il tuo progetto aggiornato e non riesco a capire quale sia il problema. Dovresti essere esplicito su ciò che vuoi ottenere ma non puoi - probabilmente in una domanda separata (+1 per pubblicare progetti di esempio tra l'altro). –