How to display more copies of an object? - ios

Objective
I need my app to display multiple instances of a UIImageView. In other words, the app should take a UIImageView and display it more times inside a view. The new UIImageViews remain identical, only their position in the view changes.
Code
To do so, I firstly declare a UIImageView:
let myImage = UIImage(named: "house")
let myImageView = UIImageView(image: myImage)
myImageView.frame = CGRectMake(view.frame.size.width/2, view.frame.size.height/2, 100, 100)
I then use a for-loop to repeat the image repetition.
for (var i = 0; i != 10; i++) {
// Distribuite UIIMageViews here
self.view.addSubview(myImageView)
}
Though, I seem to find no way to copy a UIImageView and display it more times. Declaring more than one UIImageView sounds like an inefficient solution to me.
Question
Is there any way to display an object (UIImageView) multiple times by declaring it just once?

Since UIImageView doesn't conform to the NSCopying protocol, you will have to do the copy yourself: instantiate a new UIImageView and copy manually each property you think important from the original to the new one.
The following example is creating 10 new images based on the original one. They are just copying the UIImage, but you can complete it and copy the properties you need:
let myImage = UIImage(named: "house")
let myImageView = UIImageView(image: myImage)
myImageView.frame = CGRectMake(view.frame.size.width/2, view.frame.size.height/2, 100, 100)
self.view.addSubview(myImageView)
for (var i = 0; i != 10; i++) {
var newImageView = UIImageView(image: myImageView.image)
newImageView.frame = // yourNewFrame
// Copy any else properties you need from the original image
self.view.addSubview(newImageView)
}

Related

Animated Gif inside UITextView

I had a look at this question and it didn't work. I am also trying to avoid this sort of solution. In the end I am willing to go with a CADisplayLink and change each frame manually. Still, is there a simpler way to do this?
An animated gif if just a collection of images which are displayed in sequence at a timed interval. You can do this with a UIImageView like this:
imageView.animationImages = [UIImage(named: "uploadFrame0")!, UIImage(named: "uploadFrame1")!, UIImage(named: "uploadFrame2")!, UIImage(named: "uploadFrame3")!, UIImage(named: "uploadFrame4")!, UIImage(named: "uploadFrame5")!, UIImage(named: "uploadFrame6")!, UIImage(named: "uploadFrame7")!, UIImage(named: "uploadFrame8")!]
imageView.animationDuration = 1
imageView.startAnimating()
Then you can use exclusion paths to make the text flow around it.
Use exclusion paths to define areas that are kept free, than add the image with an image view.
NSMutableArray *exclutionPaths = [NSMutableArray array];
[exclutionPaths addObject:[UIBezierPath bezierPathWithRect:CGRectInset(imageFrame, -4, 0)]];
[_textView.textContainer setExclusionPaths:exclutionPaths];
[_textView addSubview:imageView];

Creating copy of UIImageView in IOS

I am creating an app in which i draw something over imageview using a sublayer function, now i want to create a copy of that image view (over which there is everything like sublayers and image) so that my original imageview don't get effected while accessing imageview for some other purposes. Is it possible to create a copy of image view containing all the contents and use that imageview again and again for different purposes.
Thanks
I'm not sure if you're trying to copy only the contained UIImage, or an image of all the layers. Examples for both:
import UIKit
// Original UIImageView
var imageView = UIImageView()
// Copying image into new UIImageView
var _imageView = UIImageView(image: imageView.image)
// Rendering everything inside the UIImageView into a new UIImageView
UIGraphicsBeginImageContextWithOptions(_imageView.bounds.size, _imageView.opaque, 0.0);
_imageView.layer.renderInContext(UIGraphicsGetCurrentContext())
let allLayersImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
var __imageView = UIImageView(image: allLayersImage)

Can't display image in custom keyboard

i'm building custom keyboard for ios 8, so i want to display one image here but it's seems not work.
I really don't know why, here is my code:
var img = UIImageView()
img.frame = CGRectMake(0, 0, 50, 50)
img.image = UIImage(named: "interesting.jpg")
self.view.addSubview(img)
Nothing appear but if i change to display an UILabel, it's ok.
When i move this code to ViewController image display fine.
I couldn't display image in keyboard area only.
I think you could do this: UIImage(named: "interesting") and have the name of the image in the asset catalog be interesting

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)

add UIImage in CALayer

I must add a UIImageView as subview of MapView. To do this I created a layer above the MapView. In this layer I want to put my image, but I get a white rectangle and nothing else. My image is not visible.
This is the code:
- (void)viewDidLoad
{
//......
CALayer *layer = [CALayer layer];
layer.backgroundColor = [[UIColor whiteColor] CGColor];
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
layer.bounds = CGRectMake(self.mapView.bounds.origin.x,
self.mapView.bounds.origin.y, 80, 300);
}
else
{
layer.bounds = CGRectMake(self.mapView.frame.origin.x,
self.mapView.frame.origin.y, 150, 700);
}
layer.contents = (id)[UIImage imageNamed:#"myImage.png"];
//the name is correct but in the output the image is not visible
[[self.mapView layer] addSublayer:layer];
[layer setNeedsDisplay];
}
This is a general answer for the sake of future viewers. It is based on the question title rather than the details of the original question.
How to add a UIImage to a CALayer
You can add an image to a view's layer simply by using its contents property:
myView.layer.contents = UIImage(named: "star")?.cgImage
Note that the UIImage needs to be converted to a CGImage.
If you wish to add the image in its own layer, you can do it like this:
let myLayer = CALayer()
let myImage = UIImage(named: "star")?.cgImage
myLayer.frame = myView.bounds
myLayer.contents = myImage
myView.layer.addSublayer(myLayer)
Modifying the appearance
The above code produces a view like this. The light blue is the UIView and the dark blue star is the UIImage.
As you can see, though, it looks pixelated. This is because the UIImage is smaller than the UIView so it is being scaled to fill the view, which is the default it you don't specify anything else.
The examples below show variations on the layer's contentsGravity property. The code looks like this:
myView.layer.contents = UIImage(named: "star")?.cgImage
myView.layer.contentsGravity = kCAGravityTop
myView.layer.isGeometryFlipped = true
In iOS, you may want to set the isGeometryFlipped property to true if you are doing anything with top or bottom gravity, otherwise it will be the opposite of what you expect. (Only the gravity is flipped vertically, not the content rendering. If you are having trouble with the content being flipped, see this answer.)
There are two UIView examples below for every contentsGravity setting, one view is larger than the UIImage and the other is smaller. This way you can see the effects of the scaling and gravity.
kCAGravityResize
This is the default.
kCAGravityResizeAspect
kCAGravityResizeAspectFill
kCAGravityCenter
kCAGravityTop
kCAGravityBottom
kCAGravityLeft
kCAGravityRight
kCAGravityTopLeft
kCAGravityTopRight
kCAGravityBottomLeft
kCAGravityBottomRight
Related
Content mode property of a view
Drawing a UIImage in drawRect with CGContextDrawImage
CALayer Tutorial: Getting Started
it has to be
layer.contents = (id)[UIImage imageNamed:#"myImage.png"].CGImage;
You can only put a CGImage into a layer, not an UIImage directly.
I removed
[layer setNeedsDisplay];
I do not know why, but it works!
You need to set the frame of the CALayer properly, because the default is CGRectZero.
2020, full simple examples
In this example, the image is simply the size of the overall view:
class ImageyView: UIView {
private lazy var im: CALayer = {
let l = CALayer()
l.contents = UIImage(named: "some_background")?.cgImage
l.contentsGravity = .resizeAspect
layer.addSublayer(l)
return l
}()
override func layoutSubviews() {
super.layoutSubviews()
im.frame = bounds
}
}
In this example it's a Button, with small icon you're adding at the top left:
class BroadcastButton: UIButton {
private lazy var im: CALayer = {
let l = CALayer()
l.contents = UIImage(named: "your_icon")?.cgImage
l.contentsGravity = .resizeAspect
layer.addSublayer(l)
return l
}()
override func layoutSubviews() {
super.layoutSubviews()
im.frame = CGRect(origin: CGPoint(x: 2, y: 2),
size: CGSize(width: 14, height: 14))
}
}
myView.layer.contents = UIImage(named: "star")?.cgImage
This should be a comment, but I lost few hours, so I'm making it a stand alone answer.
I was doing:
myView.layer.contents = UIImage(named: "star")
can you find what the problem is? Because contents is of type Any then this just compiles fine. But the correct code is:
myView.layer.contents = UIImage(named: "star").cgImage

Resources