How do I programmatically change an image in an existing UIImageView and make it fit inside the image view's constraints? - objective-c

I have a UIImageView and when I set an image in that view using IB, the image is the correct size when I run the app (40x40). When I programmatically change the image using the code below, the new image is 400x400 or so. This is using the same image that I know works fine if it's set in IB. Do I have to scale the image before I add it to the UIImageView? I assumed auto-layout's constraints would automatically do this for me.
UIImage *messageTypeImage = [UIImage imageNamed:message.imageName];
[messageCell.imageView setImage:messageTypeImage];
[messageCell.contentView layoutIfNeeded];
The UIImageView's content mode is set to "Scale To Fill" and I've tried adding the code below both before and after calling setImage:
[messageCell.imageView setContentMode:UIViewContentModeScaleAspectFill];
[messageCell.imageView setClipsToBounds:YES];
Here's how the constraints are set up for the image view:

Are you using iOS 8 SDK? If so, try overriding layoutSubviews in your cell subclass and add this:
self.contentView.frame = self.bounds;
self.contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
There are some problems with the contentViews' of collection view/table view cells constraints/masks.

Wow. Finally found the answer here. Turns out, there's a default imageView outlet in prototype cells. I was unknowingly using that outlet and not the UIImageView I thought I was using.

Related

Draw Over Image

I'm working on some drawing code. I have that portion working great.
I want to draw over an image, but I want to still be able to see the detail of the image, the black lines, etc.
What I am working on is making a transparent UIImageView that holds the image.
I'm not sure how to get this set up properly though.
Should this be added above the other UIImageView that I color on or below it?
Here's what I have so far:
- (void)viewDidLoad
{
[super viewDidLoad];
topImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 46, 320, 370)];
[topImageView setImage:[UIImage imageNamed:#"imagesmall.png"]];
topImageView.alpha = 1.0;
topImageView.layer.opacity = 1.0;
topImageView.layer.opaque = NO;
[self.view addSubview:topImageView];
[topImageView release];
}
Thoughts anyone?
Yes, you can draw views over other views. They are drawn in the order that they're added as subviews, unless you reorder them after that.
You may need to set the opaque property for some views (this is distinct from and overrides their layer opacity), and set their backgroundColor to nil. UIImageView seems to be transparent by default, as long as its image is; some other UIView subclasses are not.
So, just what is your overlay going to be? If you just need to display one image over another, what you have here seems to work already. If you need to draw some lines programmatically, you'll need to do this:
Create a subclass of UIView.
Implement its drawRect method to display the content you need.
When you add your custom view on top of the background image, make sure it is not opaque and has no backgroundColor.
A common problem here is to find that your foreground is working, but the background isn't being loaded properly. To make sure the background is there, set the alpha of the foreground view to 0.5. You won't want to do that in production, but it will allow you to verify that both views exist.

UITableViewCell's backgroundView overlapping contentView

I am trying to set the backgroundView parameter of a UITableViewCell, but the backgroundView is overlapping the bounds of the cell. I have tried setting masksToBounds to YES, but that doesn't seem to make a difference. Please can you tell me where I am going wrong?
Here is an image showing my problem:
Here is my code:
UIImageView *iv = [[[UIImageView alloc] initWithFrame:cell.frame] autorelease];
[iv setImage:[UIImage imageNamed:#"paper"]];
[iv.layer setMasksToBounds:YES];
[cell.layer setMasksToBounds:YES];
[cell.contentView.layer setMasksToBounds:YES];
[cell setBackgroundView:iv];
Using masksToBounds doesn't work because the bounds of the cell are a rectangle.
Even if the corners of the cell are rounded, they're still part of the cell (but they contain transparent pixels). When a cell is displayed in a grouped table view, its background view (and its selected background view) is drawn in regard of its position in its section (middle, top, bottom, single).
So, if you want to provide a custom background view, you need to compute the position of the cell in its section and provide the adequate background :
either by using 4 different images
or by using the mask property of the background image's layer
or by subclassing UIView and implementing drawRect: so the graphic context is clipped before the image is drawn.
Are you setting every cell that background view, if so why don't you just set it to the table view background.

How to fade picture loading process with an UIActivityIndicatorView?

I have created a custom UITableViewCell. My custom cell contents an ImageView for picture of current article. On creation of the cell image will be loaded from Internet and displayed in the UIImageView. How can I fade then downloading process with an ActivityIndicatorView?
I'm sorry for this bad English :-) I use an online translator.
If I'm understanding you correctly, it seems like you want your UIImageView's (that are lazily downloaded in realtime) to fade in once they have fully downloaded. And while they are downloading, display the spinning UIActivityIndicatorView wheel.
Here is what I suggest:
1) Instead of defining the custom view in your table cell as a UIImageView specifically, just use the more generic UIView. This is because both classes (UIImageView and UIActivityIndicatorView) are subclasses and can be set as such.
2) Initially, for any and all cells, set the UIView to the UIActivityIndicatorView (don't forget to use "startAnimating" to get it to spin) and then on the callback function for the download completion, go to the appropriate cell and set that custom UIView to the downloaded UIImageView.
3) To achieve the fade in effect, look at the following code:
// Sets the image completely transparent
imageView.alpha = 0.0f;
// Animates the image to fade in fully over 1.0 second
[UIView animationWithDuration:1.0f animations:^{
imageView.alpha = 1.0f;
}];
4) You might need to call "setNeedsDisplay" on the table cell to refresh it's subviews after setting the new image view, and before animating it.

iOS using background in normal tableview

I was wondering how I actually use background in normal tableview(non grouped). For example take a look at the clock app and the background there. Any ideas?
You can set the background of your table view using the same techniques as the grouped table view (something like self.tableView.backgroundView = anImageView;), but your cells' background are opaque and, therefore, will hide it.
You'll then have to set, in tableView:cellForRowAtIndexPath: the background color of your cells to clearColor [UIColor clearColor] and it's backgroundView to nil.
Run the app now, and there might still be something wrong: the background of the cell's labels is possibly also opaque (I say possibly because the cells might have picked up the cell background color and changed the background color of their subviews accordingly).
If it is the case, once again, in tableView:cellForRowAtIndexPath:, set the subviews's background color to clearColor.
You can also try to set image view with your own image as backgroundView:
UIImage *yourImage = ...
UIImageView *imageView = [[UIImageView alloc] initWithImage:yourImage];
self.tableView.backgroundView = imageView;
[imageView release];

How to add a blurred view ontop of a view?

I have an NSTableView that gets reloaded. While new data is loading, I want to add a subview ontop of it with a spinner. I would like the view ontop to be semi-transparent and reveal the view beneath it, to be blurred. How would I go about doing this?
The easiest solution—significantly more so than the -bitmapImageRepEtc: one, and more applicable to Mac OS than the rasterization-scale method—is to set your overlay view to use a Core Animation backing layer, then give that layer a Core Image blur filter. It's a technique used all over the Mac OS, from the Dock menus to the menu bar itself. Interface Builder makes it trivially easy to set up, but you can do it in code as well, like this:
CALayer *backgroundLayer = [CALayer layer];
[backgroundView setLayer:backgroundLayer];
[backgroundView setWantsLayer:YES];
CIFilter *blurFilter = [CIFilter filterWithName:#"CIGaussianBlur"];
[blurFilter setDefaults];
[backgroundView layer].backgroundFilters = [NSArray arrayWithObject:blurFilter];
You should check out RMBlurredView on guthub: https://github.com/raffael/RMBlurredView
It's an easy to use subclass of NSView that does all that for you. Be sure to set setWantsLayer:YES on your parent view!
For details, check out Cocoanetics article: http://www.cocoanetics.com/2013/10/blurring-views-on-mac/
The basic technique would be to snap an image of your view, using something like the ‑bitmapImageRepForCachingDisplayInRect: method of NSView, processing that image to make it blurred (Core Image is your friend here) and then overlay your view with an NSImageView containing the blurred image.
This is fakery, of course, but that's what showmanship is about :-)
Have you tried changing the Alpha attribute for the view (for transparency)?
Also here's a link on blurring a view:
Blur Effect for UIView