I would like to add an image to the middle of the UINavigationBar. I could do it easily, but the image that I set is always pixelated no matter what resolution options i use.
I tried these two solutions, but it's still pixeled.
//1.
UIImage *logoImage = [UIImage imageNamed:#"logo.png"];
self.navigationItem.titleView = [[UIImageView alloc] initWithImage:logoImage];
//2.
CGRect myImageRect = CGRectMake(0, 0, 30, 30);
UIImageView *myImage = [[UIImageView alloc] initWithFrame:myImageRect];
[myImage setImage:[UIImage imageNamed:#"logo.png"]];
myImage.contentMode = UIViewContentModeScaleAspectFill;
self.navigationItem.titleView = myImage;
I've tried to play with the image sizes, but the result was always abnormal. Is it any other solution that I could try? Or is there any recommended resolution for the png? I tried 100 x 100 px, 44 x 44 px and 30 x 30 px.
Related
I'm using -drawViewHierarchyInRect:afterScreenUpdates: to draw a view into a UIImage, but it seems no matter what I do the results is always a very low resolution, because the image seems to need to be the same size as the original view?
The UIView is the size of the screen (in this case, 375 x 667), and the content scale factor is 2.0f.
But when I use -drawViewHierarchyInRect:afterScreenUpdates: to draw the view onto the image, it is resized (horribly) to this resolution, even though the contents is a much higher resolution.
I'm using UIGraphicsBeginImageContextWithOptions with a scale of 0.0 to create the image, so I assumed it should draw nicely, but no go. How do you draw the view hierarchy and not lose the detail?
Edit:
Here's some example code (from the answer below, which is giving the same result). It's giving me terribly down-scaled results when trying to draw the UIView hierarchy which includes a high res image:
UIGraphicsBeginImageContextWithOptions(self.view.frame.size, NO, 0);
[self.view drawViewHierarchyInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) afterScreenUpdates:NO];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
imgView.frame = self.view.bounds;
[self.view addSubview:imgView];
[self.view bringSubviewToFront:imgView];
This code works perfectly. It takes screenshot of current view and puts it to new created UIImageView. Please check that
UIGraphicsBeginImageContextWithOptions(self.view.frame.size, NO, 0);
[self.view drawViewHierarchyInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) afterScreenUpdates:NO];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
imgView.frame = self.view.bounds;
[self.view addSubview:imgView];
[self.view bringSubviewToFront:imgView];
I have a photo with size is 320 x 2560, i use a scrollview and imageview to display on iPhone. but i dont know why, if i set the imageview.frame height to 2560, the image is not fully displayed, if i increase the height to 3660, full image is displayed. i am using xcode5 with storyboard
here is the code:
UIImage *img = [UIImage imageNamed:#"photo.jpg"];
[self.imageView setImage:img];
self.imageView.frame = CGRectMake(0, 0, 320, 3660);
//self.imageView.frame = CGRectMake(self.imageView.frame.origin.x, self.imageView.frame.origin.y,img.size.width, img.size.height);
[self.scollView setContentSize:CGSizeMake((self.imageView.frame.size.width), (self.imageView.frame.size.height))];
I'm trying to get a UIImage to display at a certain spot on the screen. I've tried the initWithFrame in the code below, but it still displays at the top left corner. What should I do instead?
UIImage *headImage = [UIImage imageNamed:#"head"];
UIImageView *headView = [[[UIImageView alloc] initWithImage:headImage] initWithFrame:CGRectMake(200.0, 200.0, 400.0, 500.0)];
[self.view addSubview:headView];
Do the following: set the frame after you create the image view
UIImage *headImage = [UIImage imageNamed:#"head"];
UIImageView *headView = [[UIImageView alloc] initWithImage:headImage];
headView.frame = CGRectMake(200.0, 200.0, 400.0, 500.0);
[self.view addSubview:headView];
Cheers!
You cannot call init twice. Change your code to:
UIImage *headImage = [UIImage imageNamed:#"head"];
UIImageView *headView = [[[UIImageView alloc] initWithFrame:CGRectMake(200.0, 200.0, 400.0, 500.0)];
headView.image = headImage;
[self.view addSubview:headView];
The other answers are great if you want the image view to have a specific size. But if you want the image view's size to match the image's size as well as position the image view in a specific location then you should do:
UIImage *headImage = [UIImage imageNamed:#"head"];
UIImageView *headView = [[[UIImageView alloc] initWithImage:headImage]
CGRect frame = headView.bounds;
frame.origin.x = 200;
frame.origin.y = 400;
headView.frame = frame;
[self.view addSubview:headView];
This code has the benefit of working even if you change the size of the image.
If you don't need to change image size, then you can simple use setCenter method to move image on screen.
UIImage *headImage = [UIImage imageNamed:#"head"];
UIImageView *headView = [[UIImageView alloc] initWithImage:headImage];
[headView setCenter:CGPointMake(100, 100)]; // x, y
[self.view addSubview:headView];
I want to have gradient in my application, and my designer has made me a gradient image that is 1 pixel wide and 480 in height. How do I use this to make UIImageView stretched to full screen to make a fullscreen gradient image?
These two do not work, I get grey screen all the time:
myImageView.image = [UIImage imageNamed:#"gradient.png"];
myImageView.image = [[UIImage imageNamed:#"gradient.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(480, 1, 0, 1)];
myImageView.image = [[UIImage imageNamed:#"gradient.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0.f, 0.f, 0.f, 0.f)];
Just fix UIEdgeInsets
You should use this method, and pass UIEdgeInsetsZero:
myImageView.image = [[UIImage imageNamed:#"gradient.png"] resizableImageWithCapInsets:UIEdgeInsetsZero resizingMode:UIImageResizingModeStretch];
Using colorWithPatternImage: is easy for this:
[[self view] setBackgroundColor:[UIColor colorWithPatternImage:gradientImage]]
I know this topic has lots of Q&A, I read them all and still couldn't get it going...
I'm trying to stretch an image, while keeping its rounded edges.
This is my image (104x77px):
this is the code I'm using:
UIImage *bg = [UIImage imageNamed:#"btnBg"];
UIEdgeInsets insets = UIEdgeInsetsMake((bg.size.height - 1)/2, (bg.size.width - 1)/2, (bg.size.height - 1)/2, (bg.size.width - 1)/2);
bg = [bg resizableImageWithCapInsets:insets];
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, 50, 44)];
imgView.image = bg;
UIImageView *imgView2 = [[UIImageView alloc] initWithFrame:CGRectMake(20, 70, 250, 44)];
imgView2.image = bg;
[self.view addSubview:imgView];
[self.view addSubview:imgView2];
and this is the problem:
As you can see each image has different edges.
What am I doing wrong?!
I think what you are looking for is a stretchable image
[[UIImage imageNamed:#"someimage.png"] stretchableImageWithLeftCapWidth:5 topCapHeight:5];
As maddy points out this is deprecated in iOS 5, for those of us poor souls having to support iOS 4.3 this is what we use.
Whenever any scaling is involved, images of two different dimensions can't look quite the same. However you can break your image into three parts: the left corners, the middle section (just the parallel lines), and the right corners.
Now to create image views of different sizes, you'll keep the left and right parts constant, and scale the middle section, which won't look distorted as long as you keep the heights constant.
Note that I have give the height of fitInRect as 77 because that's the original image height. You can change this to, say, 44 but keep the number constant for all image views.
Finally, widthToPreserve HAS to be a minimum of 34 (which means the overall Rect width has to be 68 or more) because that's the width of the rounded edge in the original image.
Of course, you can simply all this by having a smaller image, if your target image view height is 44.
This code works:
-(void)viewDidAppear:(BOOL)animated
{
UIImage *img = [UIImage imageNamed:#"img"];
UIImageView *view1 = [self getImageViewFromImage:img widthToPreserve:34 fitInRect:CGRectMake(20, 20, 100, 77)];
UIImageView *view2 = [self getImageViewFromImage:img widthToPreserve:34 fitInRect:CGRectMake(20, 120, 250, 77)];
[self.view addSubview:view1];
[self.view addSubview:view2];
}
-(UIImageView*)getImageViewFromImage:(UIImage*)image widthToPreserve:(float)width fitInRect:(CGRect)rect
{
CGImageRef left, middle, right;
CGRect leftRect, middleRect, rightRect;
UIImage *leftImage, *middleImage, *rightImage;
UIImageView *leftView, *middleView, *rightView;
// calculate CGRect values for the original image
leftRect = CGRectMake(0, 0, width, image.size.height);
middleRect = CGRectMake(width, 0, image.size.width - 2*width, image.size.height);
rightRect = CGRectMake(image.size.width - width, 0, width, image.size.height);
left = CGImageCreateWithImageInRect([image CGImage], leftRect);
middle = CGImageCreateWithImageInRect([image CGImage], middleRect);
right = CGImageCreateWithImageInRect([image CGImage], rightRect);
leftImage = [UIImage imageWithCGImage:left];
middleImage = [UIImage imageWithCGImage:middle];
rightImage = [UIImage imageWithCGImage:right];
leftView = [[UIImageView alloc] initWithImage:leftImage];
middleView = [[UIImageView alloc] initWithImage:middleImage];
rightView = [[UIImageView alloc] initWithImage:rightImage];
//make your image subviews, with scaling on the middle view
[leftView setFrame:CGRectMake(0, 0, width, rect.size.height)];
[middleView setFrame:CGRectMake(width, 0, rect.size.width - 2*width, rect.size.height)];
[rightView setFrame:CGRectMake(rect.size.width - width, 0, width, rect.size.height)];
//add your 3 subviews into a single image view
UIImageView *imgView = [[UIImageView alloc] initWithFrame:rect];
[imgView addSubview:leftView];
[imgView addSubview:middleView];
[imgView addSubview:rightView];
CGImageRelease(left);
CGImageRelease(middle);
CGImageRelease(right);
return imgView;
}
Screenshot:
You can specify the residing mode for your image. The choices are UIImageResizingModeStretch and UIImageResizingModeTile.
The idea of having a stretchable image is so that you can have a small image file. You should consider using a smaller image to save space in your app bundle. Also, your left and right edge insets don't have to be in the middle. They should be just beyond the curve, which looks to be about 40 points in your image.
Here's the code to use to set the resizing mode:
bg = [bg resizableImageWithCapInsets:insets resizingMode: UIImageResizingModeStretch];
Check this out: Resizable UIImage where outside stretches and inside is kept the same
Basically the opposite of what you want. Hope it helps!