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?


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


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).


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) ???


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


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]];

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)


}
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.