autolayout - torna a altura da vista relativa à metade da altura da superview

136

estão entrando em pagamentos automáticos recentemente e estou preso ao que parece ser um exemplo de problema realmente trivial. Tenho uma visão de que quero sentar na parte superior da tela e ocupar metade da altura da tela. Simples antes da execução automática - basta colocá-lo no lugar e pedir para expandir verticalmente quando a superview é redimensionada.

Agora, eu não posso pela minha vida ver como fazê-lo. Aqui está o que recebo quando tento configurar isso:

autolayout blues

A restrição de espaço inferior é definida como "igual a 284", o que é absoluto e absolutamente inútil para mim quando mudo para o layout do iPhone4, pois mantém um espaço de 284 pontos na parte inferior da tela e reduz a exibição para não ser mais metade da tamanho da tela. E não há como definir essa restrição para igualar uma fração da altura de qualquer outra visualização.

Depois de lutar um pouco, a única maneira de pensar em fazer isso seria introduzir outra visão abaixo dessa visão, fixar suas alturas igualmente, fazer com que elas se sentassem acima e abaixo uma da outra e depois definir a segunda visão (inferior) para ficar invisível .. o que parece um pouco feio!

Estou perdendo algo óbvio?

Mete
fonte
1
Não acho feio, mas um truque inteligente para conseguir o que você deseja usando o IB. Eu fiz isso e, quando você usa nomes de elementos adequados, pode deixar claro o que está acontecendo. Você pode até ter um terceiro elemento em uma posição ou centro diferente, alterar o tamanho com base nessas duas subvisões.
perfil completo de Jelle

Respostas:

167

Isso agora é possível no IB a partir de [pelo menos] Xcode 5.1.1. Embora demorei algum tempo para descobrir, na verdade é super simples:

Primeiro, crie uma restrição básica de alinhamento superior (você também precisará configurar as restrições inferior, esquerda e direita, como o normal). Em seguida, selecione a restrição e navegue até o inspetor de Atributos :

Demonstração dos passos acima

Então você pode ajustar o multiplicador. Se você quiser, 50% da super visão deixa em 1, uma vez que está alinhada pelo centro da super. Essa também é uma ótima maneira de criar visualizações com outras porcentagens (como 25% da super visualização)

Demonstração do segundo passo acima

Firo
fonte
nice :) Eu acho que este post deve ser marcado como resposta aceita :) iOS desenvolvedor muitas vezes prefere Builder solução de interface em vez de código semelhante a solução
HQT
@ hqt, obrigado. Acho que quando a resposta aceita foi escrita, esse método não estava disponível. Às vezes, os solicitantes não revisam perguntas antigas ou se preocupam em alterar a resposta aceita. Mas, finalmente, eu estou aqui apenas para ajudar, feliz por ter ajudado!
Firo 13/09/14
3
Estou um pouco confuso. Eu tentei isso, mas apenas centraliza a visualização na superview, não ajusta a altura da visualização.
Dean
@ Dean, você precisa ter certeza de que não First Itemé . Caso contrário, sim, apenas o centralizará. Você também precisará garantir que outras restrições estejam definidas corretamente para lidar com as outras arestas da vista. View.TopView.Center Y
Firo
1
O View.Top é igual ao Superview.O multiplicador 1 do centro Y não oferece altura. Esta resposta está incompleta. Tudo o que você precisa fazer é pensar no que está dizendo e pode ver que isso dá uma linha do outro lado do centro! Gostaria de editar esta resposta para deixar claro quais outras restrições você está falando.
smileBot
184

Solução de storyboard, na qual você pode definir a proporção exata entre todas as visualizações:

Definir restrição de igualdade de altura

Agora:

Editar o multiplicador da restrição

LUCRO!!!

Resultado

PS Observe também que esse método funciona com visualizações em diferentes níveis de aninhamento e (obviamente) aplicáveis ​​à largura

Às vezes, o PPS pode ser útil "reverter o primeiro e o segundo item" da restrição ou definir o multiplicador reverso (por exemplo, 2 em vez de 0,5) (mas esses métodos não são úteis se você não entender como as visualizações se relacionam).

Fyodor Volchyok
fonte
1
O passo 2 parece não funcionar para mim. Não consigo selecionar nada no painel, exceto alternar 'Restringir para margem'. Estou tentando definir a largura de um UIImageView em um UITableViewCell para 50% da exibição do conteúdo.
DrMickeyLauer
2
ATUALIZAÇÃO: Obviamente, o construtor de interface não permite que a exibição do conteúdo seja o destino explícito de quaisquer restrições de layout automático. Eu tenho que inserir uma subvisão fictícia como filho da exibição de conteúdo para fazer isso funcionar.
precisa saber é o seguinte
1
Funciona para mim. Você precisa selecionar as duas visualizações na lista e não na tela do construtor. para porcentagens, divida a visualização menor pela visualização maior para obter o exemplo do valor multiplicador, visualização menor 25, visualização maior 135 - 25/135 = 0,185. Definir isso como o valor do multiplicador para obter uma visão de que a x1 e x2 = 25, mas escalas até com maior 6 e 6 mais etc
latenitecoder
1
Isso funcionou para mim, mas observe que eu também precisei adicionar três restrições que definissem as restrições de margem da
subvisão
Essa deve ser a resposta aceita. Primeiro, tento a resposta aceita. Não funcionou, então eu rolei para baixo e vi esta resposta e funcionou. Obrigado!
Mihir Oza
31

Depois de um pouco mais de tempo, eu vim com o seguinte.

Estou anotando isso como resposta, mas não é muito satisfatório, pois assume que você não pode fazer isso no Interface Builder, mas a restrição correta pode ser adicionada no código posteriormente como:

- (void) viewWillAppear:(BOOL)animated
{

    NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:upperview
                                                                 attribute:NSLayoutAttributeHeight 
                                                                 relatedBy:0 
                                                                    toItem:self.view
                                                                 attribute:NSLayoutAttributeHeight
                                                                multiplier:.5 
                                                                  constant:0];
    [self.view addConstraint:constraint];

}

Basicamente, define um multiplicador de 0,5 contra a altura do self.view, atuando no upperview. Eu tive que definir a prioridade da restrição de espaço vertical inferior no IB para menor que 1000 para evitar várias mensagens de tempo de execução sobre a quebra de restrições também.

Portanto, se alguém puder mostrar como fazer isso no Interface Builder, seria melhor responder à minha pergunta, caso contrário, acho que isso é o melhor possível (por enquanto) ???

Mete
fonte
3
Eu acho que isso é tão bom quanto agora. Seria bom se a Apple nos desse acesso ao valor multiplicador no IB, para que pudesse ser definido assim como a constante.
Rdelmar
3
Para quem procura esta resposta, o Xcode 5.1 agora permite que você defina o multiplicador via Interface Builder. Agora, sou capaz de configurar visualizações com metade da altura da superview, tudo via IB.
Mark Krenek
9

Um pouco mais fácil e mais direto do que o método do que a resposta de Fyodor Volchyok. -Segure o botão de controle e clique na subview. -Ainda mantendo pressionado o botão de comando, arraste o cursor para a superview e clique na superview. -Selecione "Proporção".

insira a descrição da imagem aqui

-Em seguida, clique no Inspetor de tamanhos. -Em seguida, clique duas vezes na restrição. insira a descrição da imagem aqui

-Verifique se "altura" está selecionada para os dois itens. insira a descrição da imagem aqui

-Em seguida, altere o "Multiplicador" para 0,5 por metade da tela ou qualquer fração da superview que você deseja. insira a descrição da imagem aqui

user444333222
fonte
Abordagem fácil e rápida! Obrigado companheiro
Abdullah Saeed
7

Também há outra possibilidade no código, caso você tenha duas visualizações que devem ter a mesma altura: basta definir a altura da view2 para a altura da view1 (o truque aqui não é definir a altura da view1 explicitamente).

    [self.view addConstraints:[NSLayoutConstraint
        constraintsWithVisualFormat:@"V:[topLayoutGuide]-0-[_view1]-0-[_view2(==_view1)]-0-[bottomLayoutGuide]"
                            options:0
                            metrics:nil
                              views:viewsDict]];
raio cerebral
fonte
Não sabia que era possível fazer referência a outras visualizações para larguras / alturas assim. Esta é a resposta mais limpa da IMO se você já estiver no idioma do formato visual.
loeschg
O exemplo do @brainray também é explicado em developer.apple.com aqui
alecs.popa
0

Versão rápida da resposta de Mete:

    override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.



    upperView.translatesAutoresizingMaskIntoConstraints = false


    var constraint = NSLayoutConstraint(item: upperView,
                                        attribute: NSLayoutAttribute.top,
                                        relatedBy: NSLayoutRelation.equal,
                                        toItem: self.view,
                                        attribute: NSLayoutAttribute.top,
                                        multiplier: 1,
                                        constant: 0)

    self.view.addConstraint(constraint)


    constraint = NSLayoutConstraint(item: upperView,
                                    attribute: NSLayoutAttribute.height,
                                    relatedBy: NSLayoutRelation.equal,
                                    toItem: self.view,
                                    attribute: NSLayoutAttribute.height,
                                    multiplier: 0.5,
                                    constant: 0)

    self.view.addConstraint(constraint)


    constraint = NSLayoutConstraint(item: upperView,
                                    attribute: NSLayoutAttribute.leading,
                                    relatedBy: NSLayoutRelation.equal,
                                    toItem: self.view,
                                    attribute: NSLayoutAttribute.leading,
                                    multiplier: 1,
                                    constant: 0)

    self.view.addConstraint(constraint)


    constraint = NSLayoutConstraint(item: upperView,
                                    attribute: NSLayoutAttribute.trailing,
                                    relatedBy: NSLayoutRelation.equal,
                                    toItem: self.view,
                                    attribute: NSLayoutAttribute.trailing,
                                    multiplier: 1,
                                    constant: 0)

    self.view.addConstraint(constraint)


}
user444333222
fonte