How to shrink UIImageview contents with better interpolation - ios

I'm shrinking a UIImageView but it's looks horrible and aliased.
I've tried changing the 'minifactionFilter' property but I don't see any effects.
Is there a special way to implement this? There's not much info in apple's docs.
self.imageView.layer.minificationFilter = kCAFilterLinear;
self.imageView.layer.cornerRadius = 9.0;
self.imageView.layer.masksToBounds = YES;
I know the layer properties are working as I can see the round corners but interpolation always looks the same.
kCAFilterNearest
kCAFilterLinear
kCAFilterTriLinear

Related

How to get a circle image in UIImageView

I tried to get a circle image using layer, here is my code
_compassArrow.layer.cornerRadius = _compassArrow.frame.size.width / 2;
_compassArrow.layer.masksToBounds = YES;
_compassArrow.layer.borderColor = [UIColor whiteColor].CGColor
the compassArrow is an imageview which display the compass image. And when I run my program, it looks terrible:
my actual picture
I don't know what happened to it. I've add some constraints to it, to make it has equal width with the device. Does this influence my image?
I think you set cornerRadius before your constraints are applied. Try to put this code in layoutSubviews or viewDidLayoutSubviews for example.
This way, the _compassArrow.frame.size.width value will be the one after constraints applied on it, and you'll get the correct cornerRadius.
Here is a piece of code that should allow you to do this.
_compassArrow.layer.borderWidth = 1.0
_compassArrow.layer.masksToBounds = false
_compassArrow.layer.borderColor = UIColor.whiteColor().CGColor
_compassArrow.layer.cornerRadius = profilePicture.frame.size.width/2
_compassArrow.clipsToBounds = true

Make a white label visible on top of bright image view

Basic issue:
I believe the trick is with masking, but I am not able to get a good hold of how this is set.
Basically I have a bright image (set to a uiimageview object), and I have a label at very bottom (which is added on top of the image view) needs a well readable white text on it. Right now, the white text is hard to read (because of the bright background).
What I am doing:
I am setting a mask for the image view with something like
http://cl.ly/image/0i0N1p271d42
maskContainer = [CALayer layer];
UIImage *maskImg = [UIImage imageNamed:#"mask_profile"];
[maskContainer setContents:(id)[maskImg CGImage]];
CGRect frma = maskContainer.frame;
frma.size.width = self.frame.size.width;
frma.size.height = self.frame.size.height;
maskContainer.frame = frma;
[self.imageView.layer setMask:maskContainer];
Its messed up. The overall image starts fading on top.
Can anyone share their insight on the right way to mask?
You could set a drop shadow on your text to make is stand out even over a white background:
myLabel.layer.shadowOpacity = 0.8f;
myLabel.layer.shadowOffset = CGSizeMake(0, 0);
Easiest option is to adjust the alpha on the UILabel to the desired darkness in order to make the text stand out. If you do not want to hide the image and the image itself serves as a dark background, then set the alpha on the label to 0.
The best way to do this is to place the label in a uiview then create a gradient to apply as the background to the uiview. You can create the gradient as either an image with transparency or you can draw it in code. This will create a darkening effect on you bright image just behind the label so the text will pop.

About UIImageView with round corners

I'm trying to make a UIImageView with round corners, so I used [imageView.layer setCornerRadius:5.0f]; it works but not perfectly.
If you look closely, you can see the corners of the image(I uploaded a photo, I don't know if you can see it clearly, there are blue parts in the corners). How should I remove these? thank you.
(P.S.: I also set the border of the view, is that the reason why?)
UIImageView doesn't clip to bounds by default. So while the corner radius is applied its still drawing outside of its designated area.
objc:
[imageView setClipsToBounds:YES];
swift:
imageView.clipsToBounds = true

Shadow lagging the user interface

I have around 15 views for which I apply QuartzCore shadow like this:
for button in buttonsArray {
button.layer.shadowOpacity = 0.75
button.layer.shadowColor = UIColor.blackColor().CGColor
button.layer.shadowRadius = 2.0
button.layer.shadowOffset = CGSize(width: 0.4, height: 1.2)
}
When I have a lot of this shadow in 1 view(like in this example) it really starts to slow and lag the user interface.
How can I fix it, or what other alternatives do I have? Thanks!
Check out the WWDC 2014 video 'Advanced Graphics and Animations for iOS Apps'.
https://developer.apple.com/videos/wwdc/2014/
35:50 in ... it talks about why using that type of code to generate a shadow causes extra off screen passes for the GPU as it figures out the shape of the shadow.
The suggested solution is to also use the shadowPath property on the layer if you already know the shape of the shadow...
It's a great video to watch.
Depending on how your buttons look, one idea would be to use a background image for the buttons that includes the shadow, instead of adding the shadow in code. You can also use resizableImageWithCapInsets to make for the various possible sizes of your buttons.
UIImage* image = [UIImage imageNamed:#"button.png"];
UIEdgeInsets insets = UIEdgeInsetsMake(16, 6, 16, 6); // change the insets to fit your needs
image = [image resizableImageWithCapInsets:insets];
[button setBackgroundImage:image forState:UIControlStateNormal];
Documentation on resizableImageWithCapInsets can be found at https://developer.apple.com/library/ios/documentation/uikit/reference/uiimage_class/index.html#//apple_ref/occ/instm/UIImage/resizableImageWithCapInsets:
This solution may not be fit for you, depending on how your buttons look. But using images instead of adding the shadow from code should speed up your code.

How to mask UIViews in iOS

I've seen similar questions, but haven't found workable answers.
I want to mask a UIView using a grey image (need to convert to alpha scale for masking). The UIView has background. It should be easy to mask an image, but I want to mask any UIView.
Any clues will be appreciated.
I've been working on this problem for a couple of hours and have a solution that I think will do what you want. First, create your masking image using whatever means you see fit. Note that we only need the alpha values here, all other colours will be ignored, so make certain that the method you use supports alpha values. In this example I'm loading from a .png file, but don't try it with .jpg files as they don't have alpha values.
Next, create a new layer, assign your mask to its contents and set this new layer to your UIView's own layer, like so: you should find that this masks the UIView and all its attached subviews:
UIImage *_maskingImage = [UIImage imageNamed:#"mask"];
CALayer *_maskingLayer = [CALayer layer];
_maskingLayer.frame = theView.bounds;
[_maskingLayer setContents:(id)[_maskingImage CGImage]];
[theView.layer setMask:_maskingLayer];
With this done, you can set the UIView's background colour to whatever you like and the mask will be used to create a coloured filter.
EDIT: As of iOS8 you can now mask a view simply by assigning another view to its maskView property. The general rules stay the same in that the maskView's alpha layer is used to determine the opacity of the view it is applied to.
For apps targeting iOS 8.0+ this worked well (in this case, using a gradient as the mask) It avoids any need to resize or position the mask.
// Add gradient mask to view
func addGradientMask(targetView: UIView)
{
let gradientMask = CAGradientLayer()
gradientMask.frame = targetView.bounds
gradientMask.colors = [UIColor.blackColor().CGColor, UIColor.clearColor().CGColor]
gradientMask.locations = [0.8, 1.0]
let maskView: UIView = UIView()
maskView.layer.addSublayer(gradientMask)
targetView.maskView = maskView
}
In my case, I want to remove the mask once the user starts scrolling. This is done with:
func scrollViewWillBeginDragging(scrollView: UIScrollView) {
exerDetailsTableView.maskView = nil
}
where the view is defined as an #IBOutlet:
#IBOutlet weak var exerDetailsTableView: UITableView!
Result:
I don't know the exact code off the top of my head but the basic idea is to have two UIViews. One UIView would have it's image property set to be the grey scale image and the other UIView would be set as usual the only difference is that you would position the initial UIView directly on top of the UIView containing the "normal" image.
I hope that is enough to push your idea a step further.

Resources