Eu tenho um modo de exibição que possui linhas e colunas de visualizações de imagens nele.
Se esta visualização for redimensionada, preciso reorganizar as posições das visualizações de imagens.
Esta visão é uma subvisão de outra visão que é redimensionada.
Existe uma maneira de detectar quando esta visualização está sendo redimensionada?
Respostas:
Como Uli comentou abaixo, a maneira correta de fazer isso é sobrescrever
layoutSubviews
e fazer o layout dos imageViews lá.Se, por algum motivo, você não pode criar subclasses e sobrescrever
layoutSubviews
, a observaçãobounds
deve funcionar, mesmo quando for meio suja. Pior ainda, há um risco em observar - a Apple não garante que o KVO funcione nas classes UIKit. Leia a discussão com o engenheiro da Apple aqui: Quando um objeto associado é lançado?resposta original:
Você pode usar a observação de valores-chave:
e implementar:
fonte
viewWillTransition
etc. etc.layoutSubviews
ainda é um método recomendado se, dependendo do tamanho atual da visualização, diferentes subvisualizações precisarem ser adicionadas / removidas e diferentes restrições precisarem ser adicionadas / removidas?Em uma
UIView
subclasse, observadores de propriedade podem ser usados:Sem subclassificação, observação de valores-chave com chave-caminhos inteligentes vai fazer:
fonte
frame
é uma propriedade derivada e calculada em tempo de execução. não ignore isso, a menos que você tenha um motivo muito inteligente e sabedor para fazê-lo. caso contrário: usebounds
ou (ainda melhor)layoutSubviews
.override var bounds: CGRect { didSet { layer.cornerRadius = bounds.size.width / 2 }}
bounds
ouframe
alteração funcione, dependendo de onde você coloca sua visualização na hierarquia de visualizações. Eu substituiria emlayoutSubviews
vez disso. Veja isso e essas respostas.Crie uma subclasse de UIView e substitua layoutSubviews
fonte
Swift 4 keypath KVO - É assim que detecto a rotação automática e a passagem para o painel lateral do iPad. Deve funcionar qualquer modo de exibição. Tive que observar a camada da UIView.
fonte
.layer
fez o truque! Você sabe por que usarview.observe
não funciona?Você pode criar uma subclasse de UIView e substituir o
setFrame: (CGRect) frame
método. Este é o método chamado quando o quadro (ou seja, o tamanho) da visualização é alterado. Faça algo assim:
fonte
setFrame:
não foi chamado em minhaUITextView
subclasse durante o redimensionamento causado pela rotação automática, mas simlayoutSubviews:
. Nota: Estou usando o layout automático e iOS 7.0.setFrame:
.frame
é uma propriedade derivada. Veja minha respostaMuito antigo, mas ainda assim uma boa pergunta. No código de amostra da Apple, e em algumas de suas subclasses UIView privadas, eles substituem setBounds mais ou menos como:
Substituir
setFrame:
NÃO é uma boa ideia.frame
é derivado decenter
,bounds
etransform
, portanto, iOS não necessariamente chamarásetFrame:
.fonte
setBounds:
também não é chamado ao definir a propriedade do quadro (pelo menos no iOS 7.1). Esta pode ser uma otimização que a Apple adicionou para evitar a mensagem adicional.frame
ebounds
são derivados da base da visãoCALayer
; eles apenas chamam o getter da camada. EsetFrame:
define a moldura da camada, enquantosetBounds:
define os limites da camada. Portanto, você não pode simplesmente substituir um ou outro. Além disso,layoutSubviews
é chamado excessivamente (não apenas nas alterações de geometria), portanto, também pode nem sempre ser uma boa opção. Ainda procurando ...Se você estiver em uma instância UIViewController, a substituição
viewDidLayoutSubviews
resolve.fonte
UIView
instâncias eUIViewController
instâncias. Portanto, se você tiver umaUIView
instância sem VC anexado, as outras respostas são ótimas, mas se acontecer de você ser anexado a um VC, este é o seu homem. Desculpe, não se aplica ao seu caso.