74

I have an UIView and I set a background image in this way:

self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"sfond-appz.png"]];

My problem is that back-image is not centered inside the view, but it's replayed some times to fill all the view. Is there a way to center image inside uiview and scretch to have screen size?

Note: I can't use UIImageView for background cause I have a scrollview.

rptwsthi
  • 10,094
  • 10
  • 68
  • 109
Jayyrus
  • 12,961
  • 41
  • 132
  • 214

10 Answers10

284

You need to process the image beforehand, to make a centered and stretched image. Try this:

UIGraphicsBeginImageContext(self.view.frame.size);
[[UIImage imageNamed:@"image.png"] drawInRect:self.view.bounds];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

self.view.backgroundColor = [UIColor colorWithPatternImage:image];
mr.pppoe
  • 3,945
  • 1
  • 19
  • 23
  • This is awesome answer. Most of solutions in stackoverflow point to use UIImageView which is not that good compare to this one. – Sam YC Apr 16 '13 at 07:49
  • I've tried this approach for my view but the image got messed up on landscape. anyone knows how to fix it? – tyegah123 Feb 19 '14 at 08:42
  • This solved my problem of reloading new image from document's directory in image view as well otherwise it was not updating. Thanks – djay Aug 16 '16 at 09:59
  • Hi...can i resize image without using following functions ,UIGraphicsGetImageFromCurrentImageContext() ,UIGraphicsEndImageContext() ,UIGraphicsBeginImageContextWithOptions() – Mohith P Sep 21 '16 at 13:56
  • I'm using this code to make a background image for my custom tab bar. It does fill the tab bar horizontally but vertically it leaves spaces. Here's a picture of what's happening. Any idea what's wrong? [https://imgur.com/qwbCC5J] – Saad Rehman Jul 17 '20 at 16:52
59

For Swift use this...

UIGraphicsBeginImageContext(self.view.frame.size)
UIImage(named: "ImageName.png")?.draw(in: self.view.bounds)

if let image = UIGraphicsGetImageFromCurrentImageContext(){
    UIGraphicsEndImageContext()
    self.view.backgroundColor = UIColor(patternImage: image)
}else{
    UIGraphicsEndImageContext()
    debugPrint("Image not available")
 }
mbelsky
  • 6,093
  • 2
  • 26
  • 34
Mohammad Zaid Pathan
  • 16,304
  • 7
  • 99
  • 130
  • 1
    use drawAsPatternInRect instead of drawInRect – Chandan Reddy Feb 25 '15 at 13:38
  • 1
    thanks for your suggestion,but why should I do that? – Mohammad Zaid Pathan Feb 25 '15 at 13:45
  • there was a problem with my xcode. it showed there is no method drawInRect. you are right. Thanks dude. drawAsPatternInRect is not giving the exact efect. – Chandan Reddy Feb 25 '15 at 13:52
  • how can I show background image in the middle of the screen without stretching it. – Chandan Reddy Feb 26 '15 at 09:41
  • **Case 1:** If you wants full screen background image then use correct size image for particular screens and pin it to all edges using **autolayout.** **Case 2:** If you wants specific length and width of background image then use autolayout with **FixedWidth** and **FixedHeight** and make it **Horizontally and Vertically centered.** – Mohammad Zaid Pathan Feb 26 '15 at 10:45
  • can you share some sample code of case 2. I am very new to IOS and swift. – Chandan Reddy Feb 26 '15 at 15:31
  • Download sample code from here. https://www.dropbox.com/sh/4mxoi9ogxy7olmp/AACWdOr2Wh3kacdxU4uudm9ha?dl=0 – Mohammad Zaid Pathan Feb 27 '15 at 05:07
  • 1
    I was seriously about ready to smash my monitor because I could not get a UIImage object to scale appropriately or position correctly no matter what I did. Thank you thank you thank you for this Swift adaptation of code that ACTUALLY WORKS! – Michael Nov 16 '15 at 16:58
  • Thanks, works for me! Remember to change from `var image: UIImage = UIGraphicsGetImageFromCurrentImageContext()` to `let image: UIImage = ...` to remove the Swift compiler warning. – Lauri Lehmijoki May 13 '16 at 12:11
19

Repeat:

UIImage *img = [UIImage imageNamed:@"bg.png"];
view.backgroundColor = [UIColor colorWithPatternImage:img];

Stretched

UIImage *img = [UIImage imageNamed:@"bg.png"];
view.layer.contents = img.CGImage;
Rajan Twanabashu
  • 4,586
  • 5
  • 43
  • 55
  • Thank you for your answer. But as a side note, one mustn't forget that for the repeat piece of code one has to process the image and resize it. – Georgio Sayegh Apr 13 '17 at 08:42
19

The colorWithPattern: method is really for generating patterns from images. Thus, the customization you require is most likely not possible, nor is it meant to be.

Indeed you need to use a UIImageView to center and scale an image. The fact that you have a UIScrollView does not prevent this:

Make self.view a generic view, then add both the UIImageView and the UIScrollView as subviews. Make sure all is wired up correctly in Interface Builder, and make the background color of the scroll view transparent.

This is IMHO the simplest and most flexible design for future changes.

Mundi
  • 79,884
  • 17
  • 117
  • 140
  • 1
    Also colorWithPatternImage: seems to retain the image forever, creating a memory leak. It doesn't matter for small checkerboard patterns, but if you use real images, you will run quickly out of memory... – Mackie Messer Oct 03 '14 at 03:01
4

Correct way to do in Swift 4, If your frame as screen size is correct then put anywhere otherwise, important to write this in viewDidLayoutSubviews because we can get actual frame in viewDidLayoutSubviews

   override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        UIGraphicsBeginImageContext(view.frame.size)
        UIImage(named: "myImage")?.draw(in: self.view.bounds)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        view.backgroundColor = UIColor.init(patternImage: image!)
    }
Jack
  • 13,571
  • 6
  • 76
  • 98
3

For Swift 2.1 use this...

    UIGraphicsBeginImageContext(self.view.frame.size)
    UIImage(named: "Cyan.jpg")?.drawInRect(self.view.bounds)

    let image: UIImage! = UIGraphicsGetImageFromCurrentImageContext()

    UIGraphicsEndImageContext()

    self.view.backgroundColor = UIColor(patternImage: image)
yazh
  • 701
  • 10
  • 15
1

You can use UIGraphicsBeginImageContext method to set the size of image same that of view.

Syntax : void UIGraphicsBeginImageContext(CGSize size);

 #define IMAGE(imageName) (UIImage *)[UIImage imageWithContentsOfFile:
  [[NSBundle mainBundle] pathForResource:imageName ofType:IMAGE_TYPE_PNG]]

        UIGraphicsBeginImageContext(self.view.frame.size);
        [[UIImage imageNamed:@“MyImage.png"] drawInRect:self.view.bounds];
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();

    self.view.backgroundColor = [UIColor colorWithPatternImage:IMAGE(@"mainBg")];
Jayprakash Dubey
  • 35,723
  • 18
  • 170
  • 177
1

For Swift 3.0 use the following code:

    UIGraphicsBeginImageContext(self.view.frame.size)
    UIImage(named: "bg.png")?.drawAsPattern(in: self.view.bounds)
    let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    self.view.backgroundColor = UIColor(patternImage: image)
farhad rubel
  • 2,334
  • 2
  • 22
  • 29
1

The marked answer is fine, but it makes the image stretched. In my case I had a small tile image that I wanted repeat not stretch. And the following code was the best way for me to solve the black background issue:

UIImage *tileImage = [UIImage imageNamed:@"myTileImage"];
UIColor *color = [UIColor colorWithPatternImage:tileImage];
UIView  *backgroundView = [[UIView alloc] initWithFrame:self.view.frame];
[backgroundView setBackgroundColor:color];
//backgroundView.alpha = 0.1; //use this if you want to fade it away.
[self.view addSubview:backgroundView];
[self.view sendSubviewToBack:backgroundView];
CSawy
  • 904
  • 2
  • 14
  • 25
0

Swift 4 Solution :

@IBInspectable var backgroundImage: UIImage? {
    didSet {
        UIGraphicsBeginImageContext(self.frame.size)
        backgroundImage?.draw(in: self.bounds)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        if let image = image{
            self.backgroundColor = UIColor(patternImage: image)
        }
    }
}
Maor
  • 3,340
  • 3
  • 29
  • 38