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.


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 .


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.


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 

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()
    }
}

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()
})

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.


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

}

1

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

myConstraint.constant = newValue
myView.layoutIfNeeded()

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()
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.