A Apple definiu com bastante clareza como subclasse UIView
no documento.
Confira a lista abaixo, especialmente dê uma olhada initWithFrame:
e layoutSubviews
. O primeiro se destina a configurar o quadro do seu, UIView
enquanto o último se destina a configurar o quadro e o layout de suas subvisões.
Lembre-se também de que isso initWithFrame:
é chamado apenas se você estiver instanciando sua UIView
programaticamente. Se você estiver carregando de um arquivo de ponta (ou um storyboard), initWithCoder:
será usado. E no initWithCoder:
quadro ainda não foi calculado, portanto, você não pode modificar o quadro que configurou no Interface Builder. Conforme sugerido nesta resposta, você pode pensar em chamar initWithFrame:
de initWithCoder:
para configurar o quadro.
Por fim, se você carregar a UIView
partir de uma ponta (ou de um storyboard), também terá a awakeFromNib
oportunidade de executar inicializações personalizadas de quadro e layout, pois quando awakeFromNib
é chamado, é garantido que todas as visualizações na hierarquia foram desarquivadas e inicializadas.
Do documento de NSNibAwaking
(agora substituído pelo documento de awakeFromNib
):
As mensagens para outros objetos podem ser enviadas com segurança a partir do awakeFromNib - quando é garantido que todos os objetos sejam desarquivados e inicializados (embora não necessariamente despertados, é claro)
Também é importante notar que, com o autolayout, você não deve definir explicitamente o quadro da sua exibição. Em vez disso, você deve especificar um conjunto de restrições suficientes, para que o quadro seja calculado automaticamente pelo mecanismo de layout.
Diretamente da documentação :
Métodos para substituir
Inicialização
initWithFrame:
É recomendável que você implemente esse método. Você também pode implementar métodos de inicialização personalizados, além ou em vez deste método.
initWithCoder:
Implemente esse método se você carregar sua visualização de um arquivo de ponta do Interface Builder e sua visualização exigir inicialização personalizada.
layerClass
Implemente esse método apenas se você desejar que sua exibição use uma camada diferente de Core Animation para seu armazenamento de suporte. Por exemplo, se você estiver usando o OpenGL ES para fazer seu desenho, substitua esse método e retorne a classe CAEAGLLayer.
Desenho e impressão
drawRect:
Implemente esse método se sua visualização desenhar conteúdo personalizado. Se sua vista não faz nenhum desenho personalizado, evite substituir esse método.
drawRect:forViewPrintFormatter:
Implemente esse método apenas se desejar desenhar o conteúdo da sua exibição de maneira diferente durante a impressão.
Restrições
requiresConstraintBasedLayout
Implemente esse método de classe se sua classe de exibição exigir restrições para funcionar corretamente.
updateConstraints
Implemente esse método se sua visualização precisar criar restrições personalizadas entre suas subvisões.
alignmentRectForFrame:
, frameForAlignmentRect:
Implemente esses métodos para substituir como suas visualizações estão alinhadas com outras visualizações.
Layout
sizeThatFits:
Implemente esse método se desejar que sua visualização tenha um tamanho padrão diferente do que normalmente seria durante as operações de redimensionamento. Por exemplo, você pode usar esse método para impedir que sua exibição diminua até o ponto em que as subvisões não possam ser exibidas corretamente.
layoutSubviews
Implemente esse método se você precisar de um controle mais preciso sobre o layout de suas subvisões do que os comportamentos de restrição ou de redimensionamento automático fornecem.
didAddSubview:
, willRemoveSubview:
Implemente esses métodos conforme necessário para rastrear as adições e remoções de subvisões.
willMoveToSuperview:
, didMoveToSuperview
Implemente esses métodos conforme necessário para rastrear o movimento da visualização atual em sua hierarquia de visualizações.
willMoveToWindow:
, didMoveToWindow
Implemente esses métodos conforme necessário para rastrear o movimento da sua exibição para uma janela diferente.
Manipulação de eventos:
touchesBegan:withEvent:
, touchesMoved:withEvent:
, touchesEnded:withEvent:
, touchesCancelled:withEvent:
Implementar esses métodos se você precisa para lidar com eventos de toque diretamente. (Para entrada baseada em gestos, use reconhecedores de gestos.)
gestureRecognizerShouldBegin:
Implemente esse método se sua visualização manipular eventos de toque diretamente e desejar impedir que os reconhecedores de gestos anexados acionem ações adicionais.
Gabriele Petronella
fonte
layoutSubviews
?Isso ainda aparece no Google. Abaixo está um exemplo atualizado para o swift.
A
didLoad
função permite que você coloque todo o seu código de inicialização personalizado. Como outros já mencionaram,didLoad
será chamado quando uma visualização for criada programaticamente viainit(frame:)
ou quando o desserializador XIB mesclar um modelo XIB à sua visualização viainit(coder:)
fonte
draw
método?Há um resumo decente na documentação da Apple , e isso é abordado bem na versão gratuita curso Stanford, disponível no iTunes. Apresento minha versão TL; DR aqui:
Se sua classe consiste principalmente de subvisões, o lugar certo para alocá-las é nos
init
métodos. Para visualizações, existem doisinit
métodos diferentes que podem ser chamados, dependendo se a visualização está sendo instanciada a partir do código ou de uma ponta / storyboard. O que faço é escrever meu própriosetup
método e chamá-lo de ambos osinitWithFrame:
initWithCoder:
métodos e .Se você está fazendo um desenho personalizado, você realmente deseja substituir
drawRect:
sua exibição. Porém, se sua visualização personalizada for principalmente um contêiner para subvisões, provavelmente você não precisará fazer isso.Substitua apenas
layoutSubViews
se você quiser fazer algo como adicionar ou remover uma subvisão, dependendo se estiver na orientação retrato ou paisagem. Caso contrário, você poderá deixá-lo em paz.fonte
layoutSubViews
, ele funcionou.layoutSubviews
deve definir o quadro nas visualizações filho, não na exibição em si.Pois
UIView
, o construtor designado é tipicamenteinitWithFrame:(CGRect)frame
e você deve definir o quadro lá (ou noinitWithCoder:
), possivelmente ignorando o valor do quadro passado. Você também pode fornecer um construtor diferente e definir o quadro lá.fonte
awakeFromNib