No meu aplicativo, preciso exibir imagens (texturas). Algumas são em mosaico e outras são esticadas .
No momento, eu tinha esse código funcionando:
Image(frame.image)
.resizable(resizingMode: (frame.repeatTexture == true) ? .tile : .stretch)
.frame(width: frame.width, height: frame.height)
No entanto, a renderização do .tile não é boa. A textura é cortada no eixo X. Na imagem enviada, você pode ver que o bisel não está presente à direita, está truncado.
Textura original onde há uma moldura à esquerda e à direita:
Gostaria de ter o "repeat" somente em Y, por exemplo. Parece que não há opção para isso por padrão.
Existe alguma dica, opção ou talvez outra ideia, como usar background() para forçar a textura a ficar em mosaico apenas em um eixo?
Você pode desenhar uma versão esticada da imagem usando um
GraphicsContext
, e então dividi-la em blocos usandoresizable
,Ou simplesmente desenhe a imagem inteira em mosaico com o
GraphicsContext
.Sei que isso foi aceito, mas eu queria mostrar um método diferente que pode parecer mais acessível para alguns.
Se
.resizable()
pudesse ser aplicado após definir um tamanho de quadro para a imagem ou dimensioná-la para caber, isso não seria um problema. Mas, até onde eu sei,.resizable()
deve ser o primeiro modificador ou então você obtém um erro de membro.Então a questão é: como você pode definir a largura ou a proporção da imagem primeiro, de modo que você tenha uma
Image
visualização que possa usar.resizable(resizingMode:)
nela?Você pode fazer isso redimensionando a imagem de entrada primeiro para ajustá-la à largura do quadro, renderizando-a como uma (nova) imagem e, então, usando a imagem redimensionada como entrada para a
Image
visualização que você usará.resizable(resizingMode:)
.Agora, há várias maneiras de fazer isso, como @Sweeper mostrou, mas no código abaixo eu usei
ImageRenderer
, introduzido com o iOS 16, que pode criar imagens a partir de visualizações SwiftUI. Isso significa que você pode construir sua visualização da maneira que quiser e então usar isso como entrada paraImageRenderer
, que então basicamente se tornará seu bloco repetido. Veja o exemplo no final.Aqui está o código completo:
Nota: Salvei a imagem original do tile que você forneceu, cortei-a grosseiramente e importei-a para o Assets com o nome "tile". Você também pode fornecer um nome no formato abaixo ou pode atualizar o tipo para o que for mais adequado ao seu modelo:
Esta é a imagem do bloco usada:
Exemplo opcional - Como
ImageRenderer
pode receber qualquer visualização como entrada, você pode personalizar a visualização conforme necessário. Aqui está um exemplo aproximado, usando uma sobreposição adicionada aoimageView
, que adiciona uma marca d'água que se repetirá com o tile.