UIView Background Image not showing - ios

I've defined a bg image in the Xcode Images.xcassets and want to use it as background for a view but the bg stays black. I'm using:
override func viewDidLoad()
{
super.viewDidLoad();
view.backgroundColor = UIColor(patternImage: UIImage(named: "background_ipad"));
}
this should work according to some other tickets on SO but for some reason the background stays black, not showing the image. Any ideas why this would happen?

Use this code:
SWIFT
view.layer.contents = UIImage(named:"Image_Name").CGImage
Objective-C
view.layer.contents = (__bridge id _Nullable)([UIImage imageNamed:#"Image_Name"].CGImage);

Click on the catalog image
and ensure target membership

For objective C
self.view.layer.contents = (__bridge id _Nullable)([UIImage imageNamed:#"Image_Name"].CGImage);
For Swift
self.view.layer.contents = UIImage(named:"Image_Name")!.CGImage

Related

Just want to add a darken layer or make the UIImageView darken by Swift

As people already know that this seems simple but Stackoverflow has no answers for me. Basically I want to make an image darker like the bg image of Beijing ancient building below:
to make it darker so that the tags on it can be more contrasting obvious.
I tried adding a layer which is one of the answers from Stackoverflow or adding tintColor but none of them worked, is there any method that can really work? Thank you, guys.
I'm under iOS 13 and swift 5.1
Add this UIView extension to your project
extension UIView {
func addoverlay(color: UIColor = .black,alpha : CGFloat = 0.6) {
let overlay = UIView()
overlay.autoresizingMask = [.flexibleWidth, .flexibleHeight]
overlay.frame = bounds
overlay.backgroundColor = color
overlay.alpha = alpha
addSubview(overlay)
}
//This function will add a layer on any `UIView` to make that `UIView` look darkened
}
then use it like on any UIView(In your Case yourImageView)
yourImageView.addoverlay()
Or you can specify your own overlay color and alpha value
yourImageView.addoverlay(color: .blue, alpha: 0.5)

UIImageView image does not update visibly when image property is set

I have a UIImageView whose user interaction is true and to which I have given a tap gesture recognizer, whose action handler is as follows:
#IBAction func tap(_ sender:UITapGestureRecognizer) {
let iv = sender.view as! UIImageView
let im = iv.image!
let im2 = UIGraphicsImageRenderer(size:im.size).image { _ in
UIColor.red.setFill()
UIBezierPath(rect: CGRect(origin:.zero, size:im.size)).fill()
}
iv.image = im2
}
I expect the image displayed, when I tap the image view, to be replaced by a solid red image. This works fine on my High Sierra machine running Xcode 9.4. But on my Sierra MacBook running Xcode 9.2, nothing visibly happens.
It's weird. By pausing in the debugger, I can see that the new image is being constructed correctly:
The image is being replaced, but the image view isn't being redrawn. Adding calls like setNeedsDisplay does nothing.
Moreover, if I then proceed to replace the image view's image with a different image, I see the red image!
iv.image = im2
delay(0.5) {
iv.image = im // causes im2 to appear!
}
Some sort of behind-the-scenes caching is evidently causing the image view to get behind in its display by one image.
Can anyone shed light on this? It's presumably a bug in iOS itself, and perhaps in 9.2 specifically; how would one work around it? (Obviously one could substitute another image view wholesale, but that wouldn't tell us what's going on with the caching.)
This seems to be a workaround:
iv.image = im2
delay(0.05) {
iv.image = nil
iv.image = im2
}
But what a horror... Omitting any of those assignments, or reducing the delay to zero (e.g. by calling DispatchQueue.main.async instead), causes the workaround to fail.
Encountered this problem in Xcode 13. Set the contentModel to center in the xib file
or
iv.contentMode = .center

Unable to add UIImageView Xcode Swift

For some reason I am unable to add a UIImageView to my app. This is the code I am using and I have searched for quite a while to figure this out but haven't had any luck.
super.viewDidLoad()
let cloudimage = UIImage(named: "cloud")
let cloudView = UIImageView(image: cloudimage)
self.view.addSubview(cloudView)
cloudView.frame = CGRectMake(0,0,100,200)
The image is a .png in my assets folder so I don't think it's that. I do have auto layout settings enabled if that is an issue? I know it can be an issue with moving a UIImageView around by using its frame, but I think I should still be able to place the image in the View no problem with this code.
I am not quite sure what to do any suggestions would be great, this is extremely frustrating.
If your image is nil, your UIImageView will not render anything. Try debug your view hierarchy.
https://developer.apple.com/library/tvos/documentation/DeveloperTools/Conceptual/debugging_with_xcode/chapters/special_debugging_workflows.html
http://www.raywenderlich.com/98356/view-debugging-in-xcode-6
you need to add UIimageview to main view.
self.view.addSubview(cloudView)
Try by giving the image extension also while setting to UIImage
let cloudimage = UIImage(named: "cloud.png")
let cloudView = UIImageView(image: cloudimage)
cloudView.frame = CGRectMake(0,0,100,200)
self.view.addSubview(cloudView)
Checked and its working.

Generating the image on the screen in IOS Simulator

so what I currently wish to accomplish is for an image to be printed on the background of the IOS simulator screen, so inside of my viewDidLoad, I have this
var img = UIImage(named: "paper.jpg")
This can create the image variable, but I haven't found how to display it on the screen yet. It may seem like a trivial problem, but I haven't found any documentation on this online after searching for awhile. Thanks for reading.
Refer to the UIColor documentation.
In Swift, you have to call a convenience initializer. This is because in Swift, all Objective-C class methods which return an instance of their class become convenience initializers.
Here's how it looks in Swift:
self.view.backgroundColor = UIColor(patternImage: UIImage(named: "paper.jpg"))
+ (UIColor *)colorWithPatternImage:(UIImage *)image returns a UIColor instance, so it will become a convenience initializer in Swift. Similarly, UIImage imageNamed: becomes init(patternImage image: UIImage!).
since this is the marked answer, I felt the need to add a bit more code for completion.
as #senior has posted in his answer another way to add an image to your background is by the use of adding a UIImageView as a subview like so:
let img = UIImage(named: "paper.jpg")
let imgView = UIImageView(image: img)
self.view.addSubview(imgView)
You have to add your image to an ImageView and add this to the current view as a subview,
let img = UIImage(named: "paper.jpg")
let imgView = UIImageView(image: img)
self.view.addSubview(imgView)

Modify UIImage renderingMode from a storyboard/xib file

Is it possible to modify a UIImage's renderingMode from a storyboard or xib editor?
The goal is to apply tintColor to the particular UIImageView object.
You can set the image rendering mode not in the .xib file, but in an .xcassets library.
After adding an image to an asset library, select the image and open the attributes inspector on the right side of Xcode. Find the attribute 'Render As' and set it to 'template'.
After setting an image's rendering mode, you can add a tint color to the UIImageView in a .xib or .storyboard file to adjust the image color.
This sets the property on the image wherever it's used rather than just in one interface builder file, but in almost all cases (that I've encountered) this is the behavior you want.
A few things to note:
The image color will not appear to have changed in interface builder (as of Xcode 6.1.1) but will work when the application is run.
I've experienced some bugginess with this feature and in some situations I've had to remove and re-add the UIImageView. I have not looked into that deeply.
This also works great on other UIKitComponents such as images in UIButton's and UIBarButtonItem's.
If you have a bunch of white images that are invisible in your asset library, making them black/transparent images and changing the rendering mode will make your life up to 10x better.
Here's how you can do it in .xib or storyboard files:
(Obj-C) Create a category on UIImageView:
#interface UIImageView (Utils)
- (void)setImageRenderingMode:(UIImageRenderingMode)renderMode;
#end
#implementation UIImageView (Utils)
- (void)setImageRenderingMode:(UIImageRenderingMode)renderMode
{
NSAssert(self.image, #"Image must be set before setting rendering mode");
self.image = [self.image imageWithRenderingMode:renderMode];
}
#end
(Swift 4) Create an extension for UIImageView:
extension UIImageView {
func setImageRenderingMode(_ renderMode: UIImage.RenderingMode) {
assert(image != nil, "Image must be set before setting rendering mode")
// AlwaysOriginal as an example
image = image?.withRenderingMode(.alwaysOriginal)
}
}
Then in the Identity Inspector in the xib file, add a runtime attribute:
Using the template rendering mode with a UIImageView in a storyboard or xib is very buggy, both on iOS 7 and iOS 8.
On iOS 7
The UIImage is not properly decoded from the storyboard/xib. If you inspect the imageView.image.renderingMode property in the viewDidLoad method, you will notice that it is always UIImageRenderingModeAutomatic, even if you set it to Render As Template Image in your xcassets file.
To workaround, you have to manually set the rendering mode:
self.imageView.image = [self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
On iOS 8
The UIImage is properly decoded and its renderingMode property reflects what was chosen in the xcassets file but the image is not tinted.
To workaround, you have two options:
Set the tintColor property in the User Defined Runtime Attributes instead of the Attributes inspector pane.
or
Manually reset the tintColor:
UIColor *tintColor = self.imageView.tintColor;
self.imageView.tintColor = nil;
self.imageView.tintColor = tintColor;
You can pick your preferred option, both properly tint the image.
(If you are compiling with Xcode 6.2, just doing self.imageView.tintColor = self.imageView.tintColor; is enough but this doesn’t work anymore if you are compiling with Xcode 6.3)
Conclusion
If you need to support both iOS 7 and iOS 8, you’ll need both workarounds. If you only have to support iOS 8, only one workaround is needed.
Setting imageView RenderingMode to use the tint color in the storyboard can be reduced to a one-liner:
[self.imageView setImage:[self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];
Then the image and tint color can all be set in the Storyboard.
You may fix .xib issues with an extension:
import UIKit
// fixing Bug in XCode
// http://openradar.appspot.com/18448072
extension UIImageView {
override open func awakeFromNib() {
super.awakeFromNib()
self.tintColorDidChange()
}
}
Source: https://gist.github.com/buechner/3b97000a6570a2bfbc99c005cb010bac
Amazing, this bug has been around for like 4-5 years now.
You cann't set renderingMode either from storyboard or xib. It could access by programmatically.
ex:
UIImage *unSeletedImage = [UIImage imageNamed:#"UnSelected.png"];
selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
Set tintColor & Class in Storyboard.
//
// TintColoredImageView.swift
// TintColoredImageView
//
// Created by Dmitry Utmanov on 14/07/16.
// Copyright © 2016 Dmitry Utmanov. All rights reserved.
//
import UIKit
#IBDesignable class TintColoredImageView: UIImageView {
override var image: UIImage? {
didSet {
let _tintColor = self.tintColor
self.tintColor = nil
self.tintColor = _tintColor
}
}
override init(frame: CGRect) {
super.init(frame: frame)
initialize()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initialize()
}
override init(image: UIImage?) {
super.init(image: image)
initialize()
}
override init(image: UIImage?, highlightedImage: UIImage?) {
super.init(image: image, highlightedImage: highlightedImage)
initialize()
}
func initialize() {
let _tintColor = self.tintColor
self.tintColor = nil
self.tintColor = _tintColor
}
}
It's very easy to fix
Just create class UIImageViewPDF and use it in your storyboard
IB_DESIGNABLE
#interface UIImageViewPDF : UIImageView
#end
#implementation UIImageViewPDF
- (void) didMoveToSuperview
{
[super didMoveToSuperview];
self.image = [self.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
id color = self.tintColor;
self.tintColor = color;
}
#end
Another solution is to create a UIImageView subclass:
final class TemplateImageView: UIImageView {
override func awakeFromNib() {
super.awakeFromNib()
guard let oldImage = image else { return }
image = nil
image = oldImage.withRenderingMode(.alwaysTemplate)
}
}
Then just set the class in the Interface Builder to TemplateImageView.
Simple way to be set from Storyboard:
#IBDesignable
public class CustomImageView: UIImageView {
#IBInspectable var alwaysTemplate: Bool = false {
didSet {
if alwaysTemplate {
self.image = self.image?.withRenderingMode(.alwaysTemplate)
} else {
self.image = self.image?.withRenderingMode(.alwaysOriginal)
}
}
}
}
Works fine on iOS 10 and Swift 3
I got fixed this issue by adding runtime attribute tintColor in interface builder.
NOTE : You will still need to set your image to be rendered as a template image in your Images.xcassets file.
In iOS 9 setting the tintColor property in Interface Builder is still buggy.
Note that a working solution besides writing lines directly modifying ImageView properties is to set Render As: Template Image in the asset catalog, and call e.g.:
[[UIImageView appearanceWhenContainedInInstancesOfClasses:#[[MyView class]]] setTintColor:[UIColor whiteColor]];
If you create an IBOutlet you can change it in your awakeFromNib method like so...
self.myImageView.image = [self.myImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
While #Moby's answer is more correct - this might be more succinct.
Crazy this bug is still in iOS 12.1! For storyboards/xibs: Adding a tag to the UIImageView can be a quick fix.
Swift 4.2
view.viewWithTag(1)?.tintColorDidChange()
extension UIImageView {
#IBInspectable var renderModeTemplate : Bool {
get{
return image?.renderingMode == .alwaysTemplate
}
set{
image = image?.withRenderingMode(newValue ? .alwaysTemplate:.alwaysOriginal)
}
}
}
In storyboard select UIImageView and select inspector, set property renderModeTemplate = On
In Storyboard
As Rudolf also mentioned above, I would define a simple class, like this:
import UIKit
#IBDesignable class TintImage: UIImageView{
override func layoutSubviews() {
super.layoutSubviews()
image = image?.withRenderingMode(.alwaysTemplate)
}
}
After this definition, just add an Image View to storyboard and select its custom class as TintImage. This will activate the "Tint" selection in the storyboard.

Resources