6

Stavo impostando i vincoli di un pulsante utilizzando uno storyboard. Ho visto un'opzione, "Identificatore" nelle proprietà del vincolo.Ottieni riferimento a NSLayoutConstraint utilizzando Identificatore impostato nello storyboard

Screenshot of constraint's properties

Voglio fare un riferimento a questo vincolo, per cambiare il suo valore nel codice, per spostare un oggetto.

Come posso ottenere un riferimento a questo NSLayoutContraint da questo identificativo.

ho letto la documentazione, è stato scritto come questo

@interface NSLayoutConstraint (NSIdentifier) 
/* For ease in debugging, name a constraint by setting its identifier, which will be printed in the constraint's description. 
Identifiers starting with UI and NS are reserved by the system. 
*/ 
@property (nullable, copy) NSString *identifier NS_AVAILABLE_IOS(7_0); 

@end 

Così mi sono reso conto che è a scopo di debug.

E se volessi prenderlo e usarlo? Ho visto questo collegamento, ma non è stata data una risposta soddisfacente: How to get NSLayoutConstraint's identifier by Its pointer?

+0

meglio spiegato qui http://useyourloaf.com/blog/using-identifiers-to-debug-autolayout.html –

+7

E 'molto più semplice per collegare il vincolo a una proprietà IBOutlet nella classe. Trascina da "nuovo punto di riferimento" come faresti da qualsiasi altro elemento, come un'etichetta o un campo di testo. – Paulw11

+0

Grazie per il suggerimento, ma questa cosa che sto usando, così ho voluto scrivere un pezzo di codice più piccolo, quindi sto cercando un modo migliore. @ Paulw11 –

risposta

8

Suppongo che tu abbia una presa per il pulsante in modo da avere un riferimento disponibile ad esso. Quindi, per prima cosa, recupera i vincoli della vista dal tuo pulsante. Quindi eseguire il ciclo attraverso la matrice e su ogni iterazione confrontare la proprietà identificatore di ciascun vincolo con il valore inserito in Interface Builder. Sembra che tu stia codificando in Objective-C, quindi l'esempio di codice Objective-C è sotto. Cambia @ "identificatore" con qualsiasi valore impostato in Interface Builder.

NSArray *constraints = [button constraints]; 
int count = [constraints count]; 
int index = 0; 
BOOL found = NO; 

while (!found && index < count) { 
    NSLayoutConstraint *constraint = constraints[index]; 
    if ([constraint.identifier isEqualToString:@"identifier"]) { 
     //save the reference to constraint 
     found = YES; 
    } 

    index++; 
} 
+0

Il vincolo non verrà memorizzato sul pulsante stesso. I vincoli devono essere installati su una vista antenato comune di tutte le viste coinvolte nel vincolo. Probabilmente sarà installato sul più vicino antenato comune (che potrebbe essere una delle viste coinvolte, a sua volta) ma, in teoria, potrebbe essere su un antenato più distante. Per il vincolo mostrato nella domanda, sarà sulla superview del pulsante. Questo fa parte del motivo per cui la ricerca per identificatore è un approccio così scadente. –

+0

@Ken Thomases Sì, è d'accordo che sia una scelta scadente. Tuttavia, iOS Developer ha insistito sul fatto che lui/lei vorrebbe recuperarlo dal codice per qualsiasi motivo. Il pulsante stesso è stato utilizzato per illustrare la logica, ma sì, il vincolo può essere tenuto dalla vista stessa (larghezza o altezza) o da una vista genitore dipendente dal tipo di vincolo. – strwils

+1

@KenThomases, Grazie per la risposta, e commenti, ma penso che sia scarso per iterare i vincoli completi e uno bello da matrice. È come se fossi un gruppo di vincoli e li trovassi dal gruppo. Apple deve consentire agli utenti di trovare un vincolo dal proprio identificatore. –

16

In Swift 3,

let filteredConstraints = button.constraints.filter { $0.identifier == "identifier" } 
if let yourConstraint = filteredConstraints.first { 
     // DO YOUR LOGIC HERE 
} 
7

Swift 3

ho scritto un'estensione NSView rapido che gestisce questo bene.

extension NSView { 
    func constraint(withIdentifier: String) -> NSLayoutConstraint? { 
     return self.constraints.filter { $0.identifier == withIdentifier }.first 
    } 
} 

utilizzati:

if let c = button.constraint(withIdentifier: "my-button-width") { 
    // do stuff with c 
} 
0

Per ridimensionare una serie di pulsanti all'interno di un contenitore visione comune funziona. Ogni subview/pulsante deve utilizzare un identificatore comune (ad esempio "altezza").

@IBAction func btnPressed(_ sender: UIButton) { 
    for button in self.btnView.subviews{ 
     for constraint in button.constraints{ 
      if constraint.identifier == "height"{ 
       constraint.constant = constraint.constant == 0 ? 30:0 
      } 
     } 
    } 
    UIView.animate(withDuration: 0.3) {() -> Void in 
     self.view.layoutIfNeeded() 
    } 
} 
Problemi correlati