Como atualizar a restrição de altura constante de um UIView programaticamente?

102

eu tenho um UIView e defino as restrições usando o Xcode Interface Builder.

Agora eu preciso atualizar isso UIView's constante de altura programaticamente.

Tem uma função que funciona assim myUIView.updateConstraints(), mas não sei como usar.

Chris Mikkelsen
fonte
Pegue a saída da restrição de altura e defina programaticamente
iMuzahid
você pode usar este link ou este link para referências.
Amna Farhan
Esta é uma maneira de atualizar uma ou várias restrições. stackoverflow.com/a/54171693/8861442
Sarath Kumar Rajendran

Respostas:

217

Selecione a restrição de altura do construtor de interface e obtenha uma saída dela. Então, quando você quiser alterar a altura da vista, você pode usar o código abaixo.

yourHeightConstraintOutlet.constant = someValue
yourView.layoutIfNeeded()

Método updateConstraints()é um método de instância de UIView. É útil quando você está definindo as restrições de maneira programática. Ele atualiza as restrições para a vista. Para mais detalhes clique aqui .

Parth Adroja
fonte
58
Hoje aprendi que Constraints podem ser transformadas em uma válvula de escape e, a partir daí, posso fazer o que quiser com elas. Obrigado
Chris Mikkelsen
@ParthAdroja, mano, você poderia dar uma olhada na minha pergunta stackoverflow.com/questions/46034278/… ?
May Phyu,
Não tenho um arquivo xib e como definir yourHeightConstraint em um UIView programaticamente?
newszer
@newszer, você precisa olhar para outro tópico para esse stackoverflow.com/questions/31651022/…
Parth Adroja
Ouvi dizer que devemos chamar layoutIfNeeded após a restrição de constante de alteração. porque? e às vezes eu chamo layoutIfNeeded dentro de viewWillLayoutSubviews e viewDidLayoutSubviews. está tudo bem?
mnemônico
104

Se você tiver uma visualização com várias restrições, uma maneira muito mais fácil sem ter que criar vários pontos de venda seria:

No construtor de interface, dê a cada restrição que deseja modificar um identificador:

insira a descrição da imagem aqui

Então, no código, você pode modificar várias restrições como:

for constraint in self.view.constraints {
    if constraint.identifier == "myConstraint" {
       constraint.constant = 50
    }
}
myView.layoutIfNeeded()

Você pode atribuir a várias restrições o mesmo identificador, permitindo agrupar as restrições e modificar tudo de uma vez.

George Filippakos
fonte
Isso funciona bem, mas estou achando mais fácil usar apenas uma coleção de outlet regular para agrupar as restrições. Por exemplo, na visualização com a qual estou trabalhando, há 47 restrições, mas apenas 6 que desejo alterar no tempo de execução, portanto, é um loop muito menor. Isso também não requer manter as strings em sincronia entre dois lugares diferentes.
Gary Z
1
Obrigado George por esta dica. É uma ajuda real com alguns layouts atuais com os quais estou brincando.
Jim Hillhouse,
1
BONITO
William Yang
Oi, estou usando da mesma forma, mas nunca vai no caso if e dei o mesmo identificador.
Rob13
Eu queria saber se seria possível nomear restrição. Ótima resposta!
ShadeToD
35

Mude HeightConstrainte WidthConstraintsem criar IBOutlet.

Nota: Atribua restrição de altura ou largura no Storyboard ou arquivo XIB. depois de buscar esta restrição usando esta extensão.

Você pode usar esta extensão para obter uma restrição de altura e largura:

extension UIView {

var heightConstraint: NSLayoutConstraint? {
    get {
        return constraints.first(where: {
            $0.firstAttribute == .height && $0.relation == .equal
        })
    }
    set { setNeedsLayout() }
}

var widthConstraint: NSLayoutConstraint? {
    get {
        return constraints.first(where: {
            $0.firstAttribute == .width && $0.relation == .equal
        })
    }
    set { setNeedsLayout() }
}

}

Você pode usar:

yourView.heightConstraint?.constant = newValue 
AshvinGudaliya
fonte
2
Existe um método que first(where: ...)você pode usar imediatamente em vez de filter+first
Vyachaslav Gerchicov
13

Arraste a restrição para o seu VC como um IBOutlet. Em seguida, você pode alterar seu valor associado (e outras propriedades; verifique a documentação):

@IBOutlet myConstraint : NSLayoutConstraint!
@IBOutlet myView : UIView!

func updateConstraints() {
    // You should handle UI updates on the main queue, whenever possible
    DispatchQueue.main.async {
        self.myConstraint.constant = 10
        self.myView.layoutIfNeeded()
    }
}
dylanthelion
fonte
9

Você pode atualizar sua restrição com uma animação suave, se quiser, veja o trecho de código abaixo:

heightOrWidthConstraint.constant = 100
UIView.animate(withDuration: animateTime, animations:{
self.view.layoutIfNeeded()
})
Hafiz Muhammad Farooq Rasheed
fonte
4

Se o método acima não funcionar, certifique-se de atualizá-lo no bloco Dispatch.main.async {}. Você não precisa chamar o método layoutIfNeeded () então.

Nupur Sharma
fonte
4

Primeiro conecte a restrição de altura em nosso viewcontroller para criar IBOutlet como o código abaixo mostrado

@IBOutlet weak var select_dateHeight: NSLayoutConstraint!

em seguida, coloque o código abaixo em exibição carregou ou dentro de qualquer ação

self.select_dateHeight.constant = 0 // we can change the height value

se estiver dentro de um botão, clique

@IBAction func Feedback_button(_ sender: Any) {
 self.select_dateHeight.constant = 0

}
Nimisha joshy
fonte
1

Para atualizar uma restrição de layout, você só precisa atualizar a propriedade constante e chamar layoutIfNeeded depois.

myConstraint.constant = newValue
myView.layoutIfNeeded()
Fran Martin
fonte
1
Create an IBOutlet of NSLayoutConstraint of yourView and update the constant value accordingly the condition specifies.

//Connect them from Interface 
@IBOutlet viewHeight: NSLayoutConstraint! 
@IBOutlet view: UIView!

private func updateViewHeight(height:Int){
   guard let aView = view, aViewHeight = viewHeight else{
      return
   }
   aViewHeight.constant = height
   aView.layoutIfNeeded()
}
CrazyPro007
fonte