0

I want o create a simple background by tiling an image in a Z-stack.

I'm trying to scale down a large image while maintaining its aspect ratio, then tiling it across the entire screen to serve as a background.

I want to avoid editing the original image itselt and resizing it in a seperate software.

I tried the following - but only get a small portion of the image covering the screen:

import SwiftUI

struct MenuView: View {
    
    var body: some View {
        
        ZStack {
            Image("BackgroundDoodle")
                .resizable(resizingMode: .tile)
                .frame(width: .infinity, height: .infinity, alignment: .center)
                .ignoresSafeArea()
                .opacity(0.8)
        }
    }
}
TheDoctor
  • 13
  • 4
  • From what I see, you say you want to tile the image but you set its size to infinity. You should set its size to something smaller than screen, then resize to tile. – Ptit Xav Jul 02 '23 at 07:11
  • I tried adding 'frame(width:100)' but still didn't work – TheDoctor Jul 02 '23 at 08:50

1 Answers1

0

You can resize the image using UIKit :

import SwiftUI import UIKit

struct MenuView: View  {
    
    var body: some View {
        
        ZStack {
            smallImage()
                .resizable(resizingMode: .tile)
                .frame(width: .infinity, height: .infinity, alignment: .center)
                .ignoresSafeArea()
                .opacity(0.8)
        }
    }
    
    @ViewBuilder
    func smallImage() -> Image {
        let uiImage = UIImage(named: "BackgroundDoodle")!
        
        Image(uiImage: resizeImage(image: uiImage, targetSize: CGSize(width: 100, height: 100))!)
    }

resizeImage taken from How to Resize image in Swift?

    func resizeImage(image: UIImage, targetSize: CGSize) -> UIImage? {
        let size = image.size
        
        let widthRatio  = targetSize.width  / size.width
        let heightRatio = targetSize.height / size.height
        
        // Figure out what our orientation is, and use that to form the rectangle
        var newSize: CGSize
        if(widthRatio > heightRatio) {
            newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio)
        } else {
            newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio)
        }
        
        // This is the rect that we've calculated out and this is what is actually used below
        let rect = CGRect(origin: .zero, size: newSize)
        
        // Actually do the resizing to the rect using the ImageContext stuff
        UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
        image.draw(in: rect)
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return newImage
    }
}
Ptit Xav
  • 3,006
  • 2
  • 6
  • 15