Posso usar setFrame e autolayout na mesma vista?

Eu quero adicionar padding a todos os meus botões, então eu subclass o UIButton e, entre outras alterações, eu queria adicionar um preenchimento fixo usando o método setFrame. Tudo estava funcionando, exceto por setFrame. Eu verifiquei e descobri que, se eu desmarcar “usando o AutoLayout” nessa visualização, posso usar o setFrame e ele funcionará. Existe uma maneira de contornar isso? Eu realmente quero usar o autolayout, porque ele ajuda a fazer com que o aplicativo fique bem nos dispositivos iPhone 5 e anteriores. Mas eu também gostaria de usar setFrame na minha subclass, para tornar minha vida um pouco mais fácil.

Resumindo, minha pergunta é: Posso usar o autolayout e também ajustar o quadro de um UIView programaticamente?

Sim, isso pode ser feito.

Se você definir o translatesAutoresizingMaskIntoConstraints = YES da view, as chamadas para setFrame: serão traduzidas automaticamente no tempo de execução em restrições de layout com base no autoresizingMask atual da view. Isso permite que você misture layout baseado em quadro com layout baseado em restrição.

Por exemplo, você pode usar o Auto Layout para definir o layout de todas as subvisões de uma vista, mas ainda chamar setFrame: para definir o tamanho e a posição da própria vista. Do seu ponto de vista, você está fazendo layout com uma mistura de Layout automático e manipulação direta de frameworks. Mas o sistema está realmente usando restrições para lidar com tudo.

No entanto, há uma grande advertência sobre o uso do translatesAutoresizingMaskIntoConstraints .

Quando você faz isso, você ainda precisa se certificar de que essas restrições automáticas podem ser satisfeitas com o resto de suas restrições .

Então, por exemplo, suponha que já existam restrições que determinam o tamanho e posição de sua visão, e então você também configura translatesAutoresizingMaskIntoConstraints = YES e chamado setFrame: A chamada para setFrame: gerará novas restrições na visualização, o que provavelmente entrará em conflito com as restrições já existentes.

(Na verdade, esse erro acontece com frequência. Se você vir uma mensagem de log reclamando de restrições conflitantes e uma dessas restrições for uma restrição NSAutoresizingMaskLayoutConstraint , o que você está vendo é um conflito com uma restrição automática. Esse é um erro fácil, porque translatesAutoresizingMaskIntoConstraints = YES é o valor padrão, então se você está configurando restrições no código, você precisa se lembrar de desativá-lo se não quiser essas restrições automáticas.)

Por outro lado, suponha novamente que já existam restrições que determinam o tamanho e a posição de sua visão, mas você define translatesAutoresizingMaskIntoConstraints = NO antes de chamar setFrame: Nesse caso, suas chamadas setFrame: não produziriam novas restrições, portanto, não haveria conflito entre restrições separadas . No entanto, nesse caso, ainda há um “conflito” entre as restrições e o valor do quadro que você definiu . Na próxima vez que o Auto Layout for chamado, ele verá as restrições já existentes na visualização, calculará o valor de quadro que elas exigem e definirá o quadro como o próprio valor necessário, destruindo o valor definido manualmente.

Para mais detalhes, confira a seção “Adotando Auto Layout” no Cocoa Auto Layout Guide da Apple.

O que acabou sendo a coisa mais fácil para mim foi remover a visão que eu queria mover / resize de sua super visão, definir seu frame e então adicioná-lo de volta. Por exemplo, pegue um UILabel personalizado em uma subclass UITableViewCell :

 [cell.myLabel removeFromSuperview]; cell.myLabel.frame = someFrameIGenerated; [cell.contentView addSubview:cell.myLabel]; 

Algo que funcionou para mim foi simplesmente adicionar um IBOutlet para minhas restrições ao controlador de visualização e, em seguida, alterar a propriedade constant na saída.

Por exemplo, para alterar a origem x de uma vista, defina uma saída da restrição principal dessa vista para o seu controlador. Em outras palavras, crie uma saída @IBOutlet var labelXOrigin: NSLayoutConstraint! . Então, quando você quiser ajustar a posição x, simplesmente faça algo como

 self.labelXOrigin.constant = 20.0 // Or whatever origin you want to set. 

A melhor maneira de definir o quadro de subvisualização é o método viewWillLayoutSubviews em projetos de autolayout.

set property translatedAutoresizingMaskIntoConstraints = true, isso funcionará depois que a visualização apareceu ou a guia no botão para definir, logo após a exibição aparecer.

Se o seu aplicativo não suporta várias orientações de dispositivos.

Em viewDidLoad, defina o quadro da visualização que você deseja resize

 - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. [aView setFrame:CGRectMake(15, 15, 100, 100)]; } 

Em seguida, em viewDidLayoutSubviews :

 -(void)viewDidLayoutSubviews { [self.view setTranslatesAutoresizingMaskIntoConstraints:NO]; } 

Não tenho certeza, mas acho que se você usar essa solução, mudar uma orientação para outra pode causar problemas

Intereting Posts