UIViewContentModeScaleAspectFill não recorte


144

Estou tentando desenhar algumas imagens em miniatura em um tamanho fixo (100x100) usando UIImageView. Eu definir o tamanho do quadro de meu ponto de vista para ser 100x100, e definir o contentModeque UIViewContentModeScaleAspectFill.

Meu entendimento é que isso deve fazer com que a imagem seja desenhada no tamanho definido, e a imagem preencherá a área da imagem e recortará todas as partes da imagem que estiverem fora do tamanho definido para a visualização da imagem. No entanto, a imagem ainda é desenhada maior ou menor que o tamanho de 100 x 100 definido por ela.

Se eu definir contentModecomo UIviewContentModeScaleToFill, a imagem será desenhada exatamente 100x100, mas será distorcida para caber nessas dimensões. Alguma idéia de por que o preenchimento de aspecto não está aparando como esperado?

Aqui está o meu código:

_photoView = [[UIImageView alloc] initWithImage:photoImage];
_photoView.contentMode = UIViewContentModeScaleAspectFill;
[self addSubview:_photoView];

CGRect photoFrame = _photoView.frame;
photoFrame.size = CGSizeMake(100, 100);
_photoView.frame = photoFrame;

Para ilustrar melhor, aqui está uma captura de tela do que estou vendo. Os quadrados verdes são os UIViewque UIImageVieweu estou trabalhando. Defina a cor do plano de fundo para verde e o quadro da vista para 100x100. Como teste, eles UIImageViewssão dimensionados para 50x50. Como você pode ver, ao usar o ...AspectFill, as imagens não são dimensionadas para 50x50 e, em alguns casos, são deslocadas de onde eu gostaria. Ao usar ...ScaleToFill, eles são dimensionados corretamente, mas a imagem está distorcida.

Captura de tela ilustrando o problema

Respostas:


352

Você pode tentar ajustar o clipe para limites

[_photoview setClipsToBounds:YES];

Ou diretamente no seu Storyboard / Xib, se você puder:

insira a descrição da imagem aqui


10
Era isso - obrigado. (Eu adicionei a imagem acima para melhor mostrar o que eu estava vendo, mais como um exemplo se alguém se depara com esta questão.)
Josh Buhler

3
Em InterfaceBuilder, renomeado (inutilmente) para "Clips subviews" (NB: neste caso, não clib "subviews", o nome é errado: clips AUTO E subviews)
Adam

3
Marcar a opção 'Clip Subviews' no arquivo NIB faz a mesma coisa. Felicidades.
Codeburn

Mas o que dizer se você quiser adicionar uma sombra usando a propriedade CALayer :( adicionando outra visão por trás dele não é o ideal para mim
Rambatino

Se você estiver usando o Layout automático como eu, há outra causa possível, que é NSLayoutConstraint "UIView-Encapsulated-Layout-Height" quebrando as restrições de tamanho do UIImageView.
ewiinnnnn

8

Se você deseja expandir seu conhecimento, há um artigo realmente bom sobre como a pilha do iOS UIView é renderizada . Há também um artigo mais aprofundado sobre todo o pipeline de desenho .

Em suma:

  1. Rasterização - Todo o conteúdo da visualização é rasterizado (desenhado ou um buffer de pixel fora da tela) no espaço coordenado dos limites da Visualização. Podem ser dados de imagem ou desenho personalizado (por exemplo drawRect:), mas conteúdo de subvisualização. Essa rasterização leva em conta a contentModepropriedade.

    Qualquer coisa fora dos limites de uma vista é descartada.

  2. Composição - Os resultados são compostos (desenhados uns sobre os outros) da subvisão às supervisões. Isso usa a propriedade de quadro da subvisão.

    Se a clipsToBoundspropriedade estiver YESna superview, ela descartará o conteúdo da subview fora de seus limites.


2

teve o mesmo problema e foi resolvido marcando "Clip Subviews".

A imagem estava aparecendo corretamente para todas as visualizações (3,5,4,4,7,5,5, ipad) na visualização do storyboard, mas não no simulador.

Depois de marcar "Subvisões de clipe", o problema foi resolvido. :)


1

Verificar "Subvisões de clipe" diretamente no Storyboard / Xib também funcionou para mim. insira a descrição da imagem aqui


0

Minhas sub-visualizações foram redimensionadas e eu percebi que era porque o xib tinha o layout automático definido: insira a descrição da imagem aqui


0

Se tudo falhar,

faça os clipes nos limites do método viewDidLayoutSubviews.

Exemplo:

  override func viewDidLayoutSubviews() {

    imageProfile.layer.cornerRadius = imageProfile.bounds.size.width/2
    imageProfile.clipsToBounds = true
    imageProfile.layer.masksToBounds = true
 }
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.