Drawing multiple UIImageViews with the same UIImage - ios

I am trying to draw a line using multiple UIImageView of the same circle image.
I have tried the following:
let imageName = "circle.jpg"
let image = UIImage(named: imageName)
for var i in 0..<100 {
i += 1
let imageView = UIImageView(image: image!)
imageView.frame = CGRect(x: i, y: 200, width: 25, height: 25)
view.addSubview(imageView)
}
This produces one circle at the position (100, 200). This happens because the same UIImageView is being added to the subview so it is only updating the position rather than adding a new UIImageView. If I create a new UIImageView named "imageView1" and add it to the subview, it will create a new circle.
For the purpose of forming a line by overlapping the UIImageViews of these circles, manually creating a UIImageView for each circle is obviously inefficient.
So, how can I use the same UIImage to draw multiple UIImageViews?
Any other suggestions on how I can get around accomplishing this?

You need a circle to form a line like this
Well here the code I used for this using While loop
let imageName = "synergy-many-people-turning-in-gears_gg55375354.jpg"
let image = UIImage(named: imageName)
var i = 0
while(i<100)
{
let imageView = UIImageView(image: image!)
imageView.frame = CGRect(x: i, y: 200, width: 25, height: 25)
view.addSubview(imageView)
i = i + 25//Here I set it to the width so that the images don't overlap
//you can use any value for the desired effect it just sets the location
//of X-Co-ordinate where the next image would be added
}

I would quickly try out something like this (didn't test it though):
var imageView = UIImageView(image: image!)

Creating multiple UIImageViews is the thing you need to do. If this will be to slow (btw you should place your image inside assets catalogue to allow caching and improve performance), you should switch to lower level api. Check iOS - An easy way to draw a circle using CAShapeLayer
And, btw, why do you change i variable inside loop, this is very bad practice

Related

How to make a UIImage Scrollable inside a UIScrollView?

I currently have a ScrollView and inside the ScrollView i have a UIImageView.
I get different image sizes from my server and most images are larger than the bounds of my screen.
I would like to scroll through the image if it is bigger than my screen.
Something like this....
This is what i have tried so far.
let image = UIImage(named: "myImg")
let heightInPoints = image?.size.height
let heightInPixels = heightInPoints ?? 0 * image!.scale
let widthInPoints = image?.size.width
let widthInPixels = widthInPoints ?? 0 * image!.scale
self.imageView.frame = CGRect(x: 0, y: 0, width: widthInPixels, height: heightInPixels) //= image
self.imageView.image = image
scrollView.contentSize = CGSize(width: imageView.frame.width, height: imageView.frame.height)
But it doesn't seem to work. Either it only scrolls vertically or horizontally or it never scrolls.
What am I doing wrong. Or is there a better approach to get this effect ?
Solution 1. Updating Frames
Firstly, make sure the views hierarchy is correctly setup (the imageView is added to the scrollView):
scrollView.addSubview(imageView)
Then I'd suggest rewriting this code as something like:
let image = UIImage(named: "myImg")
imageView.image = image // setup image to imageView
imageView.frame.size = image?.size ?? .zero // setup image size or zero to imageView
scrollView.contentSize = image.size ?? .zero // setup image size or zero as a content size
Solution 2. Using constraints
There is also another solution using constraints instead of manually setting up the sizes. This takes a bit more code but doesn't require sizes recomputing when you change the image.
scrollView.addSubview(imageView) // Setup the views hierarchy
imageView.translatesAutoresizingMaskIntoConstraints = false // Make sure constraints won't interfere with autoresizing mask
NSLayoutConstraint.activate(
[
imageView.leftAnchor.constraint(equalTo: scrollView.leftAnchor), // attaching to the left
imageView.topAnchor.constraint(equalTo: scrollView.topAnchor), // attaching to the top
imageView.rightAnchor.constraint(equalTo: scrollView.rightAnchor), // attaching to the right
imageView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor) // attaching to the bottom
]
)
Then we replace existing image with a new one like this:
imageView.image = UIImage(named: "myImg")
Both approaches work for me in Playground. So, if these still won't work for you, please share more information about how you set up the hierarchy and additional parameters of the scroll view.

Achieve exact control of scale and offset of UIImage in UIImageView

I currently have a UIImageView with an image loaded inside with the contentMode being set to scaleAspectFill. Is there a way to specify an exact section of the image to show instead of the default center, or am I approaching this the wrong way?
Swift Code:
basketballImage = UIImageView()
basketballImage.contentMode = .scaleAspectFill
basketballImage.clipsToBounds = true
basketballImage.image = UIImage(named: "Basketball")
Original Image
Desired Result
Failed Example 1: With contentMode = .scaleAspectFill
Failed Example 2: With contentMode = .top
There's no way for iOS to know what you really want since your scaling is arbitrary.
You can effectively crop (zoom-in) by setting the contentScaleFactor property. Aspect-fit is unrelated to your goal.
Now, the arbitrary vertical offset requires an affine transform, but only works with a container UIView to maintain the layout. You have to transform the entire UIImageView frame within its parent (unless you want to get very fancy and override the draw method or re-implement UIImageView with an affine-transform hook).
I achieved roughly what you want by installing that image at 2x resolution and using:
override func viewDidLoad() {
super.viewDidLoad()
let offset: CGFloat = 120.0
let scale: CGFloat = 3.0
/* imageView is a *child* of imageContainer and constrained to be exactly the same size and position */
imageContainer.clipsToBounds = true
imageView.image = UIImage(named: "basketball")
imageView.contentMode = .center
imageView.contentScaleFactor = scale
imageView.transform = CGAffineTransform(translationX: 0, y: offset)
}
It's harder than I'd like, what with another layer of nesting, but UIImageView is just not that sophisticated.

ios swift create rounded profile image like twitter, instagram,

I would like to create a very simple image editor, same as twitter (for the profile image)
I know how to pinch or move an image.
But i don’t know how to create the "circle layer" and just keep this part of the image, like this :
Make sure to import QuarzCore.
func maskRoundedImage(image: UIImage, radius: CGFloat) -> UIImage {
let imgView: UIImageView = UIImageView(image: image)
let layer = imgView.layer
layer.masksToBounds = true
layer.cornerRadius = radius
UIGraphicsBeginImageContext(imgView.bounds.size)
layer.render(in: UIGraphicsGetCurrentContext()!)
let roundedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return roundedImage!
}
https://github.com/andreaantonioni/AAPhotoCircleCrop
Each view has an underlying layer onto which you apply a corner radius. Then you must apply clipToBounds on that layer in order to apply that mask to the overlying UIView. The corner radius must be half the width of the view in order to get a circle effect. Otherwise the corners of the view will be rounded.
For example:
let square = UIView()
square.center = view.center
square.bounds.size = CGSize(width: 100, height: 100)
square.backgroundColor = .red
view.addSubview(square)
square.layer.cornerRadius = 50
square.clipsToBounds = true
Above mentioned ways are good, But you can not achieved exact output as in above image E.g You can not get alpha effect.
I suggest simple way to do it.
1) Add new image to project with transparent background with Opocity and circle.
2) Add new imageView above to mainview as below.
let image = UIImageView(frame: view.bounds)
mage.image = UIImage.init(named:"imageName")
view.addSubview(image)
Then output should be as per your requirement.

How to center an image in navigationBar across all UIViewControllers? Swift / Obj-C

Problem visually:
I have tried putting the image in the center of its own frame with no luck. I have also tried to center it with playing the x of the CGRect with no luck either. I presume I can just put an empty icon with the same background as the navigation bar; however, I don't want to do it that way. I might have 2-3 icons on the right; then what?
let image = UIImage(named: "some_logo")!
let imageSize = CGSizeMake(60, 42)
let marginX: CGFloat = (self.navigationController!.navigationBar.frame.size.width / 2) - (imageSize.width / 2)
let imageView = UIImageView(frame: CGRect(x: marginX, y: 0, width: imageSize.width, height: imageSize.height))
imageView.image = image
imageView.contentMode = .ScaleAspectFit
self.navigationItem.titleView = imageView
I prefer swift but obj-c solutions are welcomed as well.
Any pointers appreciated.
This app has nothing to do with KIA, it is just some logo I got off the google search, searching "some logo".
I have faced the same issue. Then i tried one code shown below.
override func viewDidAppear(animated: Bool) {
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 150, height: 40))
imageView.contentMode = .ScaleAspectFit
let image = UIImage(named: "googlePlus")
imageView.image = image
navigationItem.titleView = imageView
}
This Code working fine when i tested with Left & Right Bar Button.
But in my previous code there is no Right Bar Button.
So the image is moving towards right.
For solving this i created a Right Bar Button & change the Tint color to clear color.
So everything seems to be working fine. This is one Temporary Solution for your problem.
The easiest way of doing this is in Interface Builder.
Simply drag a 'NavigationItem' from the object library and place it into your ViewController, then place a UIView where the title goes (ensure you set the background to 'clear')
Then place a UIImageView into that view and set the image in the Attributes Inspector to your required image. Scale your UIImage accordingly and set your your constraints accordingly.
I created an extension for solving this problem using the hint of #idrougge.
In order to center the title view image no matter what buttons you have, a content view is set as title view, then the image view is added as child of the content view. Finally, using constraints the image view is aligned inside its parent (content view).
import UIKit
extension UIViewController {
func addLogoToNavigationBarItem() {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.heightAnchor.constraint(equalToConstant: <your_height>).isActive = true
imageView.contentMode = .scaleAspectFit
imageView.image = <your_image>
//imageView.backgroundColor = .lightGray
// In order to center the title view image no matter what buttons there are, do not set the
// image view as title view, because it doesn't work. If there is only one button, the image
// will not be aligned. Instead, a content view is set as title view, then the image view is
// added as child of the content view. Finally, using constraints the image view is aligned
// inside its parent.
let contentView = UIView()
self.navigationItem.titleView = contentView
self.navigationItem.titleView?.addSubview(imageView)
imageView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
imageView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
}
}
I hope this helps someone,
Xavi
As question heading stated "Swift / Obj-C" so I am sharing code of Obj-C :
UIImageView *titleImage = (UIImageView *)self.navigationItem.titleView;
titleImage = [[UIImageView alloc]initWithFrame:CGRectMake((self.navigationController.navigationBar.frame.size.width/2) - (100/2), 0, 100,self.navigationController.navigationBar.frame.size.height)];
//setting the image for UIImageView
titleImage.image = [UIImage imageNamed:#"someLogo"];
titleImage.contentMode = UIViewContentModeCenter;
self.navigationItem.titleView = titleImage;
Had same issue on phones with smaller sizes. Image in title was moving to right. Causing this issue back button -> [back_button][title_view]. Its centered when there is no back button or there is right bar button. Richard Hope's was right, you just need to put UIView first, and then put UIImageView as subview. Programmatically could be done like this.
private var imageView: UIView {
let bannerWidth = navigationBar.frame.size.width * 0.5 // 0.5 its multiplier to get correct image width
let bannerHeight = navigationBar.frame.size.height
let view = UIView()
view.backgroundColor = .clear
view.frame = CGRect(x: 0, y: 0, width: bannerWidth, height: bannerHeight)
let image = UIImage(named: "your_image_name")
let imageView = UIImageView(image: image)
imageView.contentMode = .scaleAspectFit
imageView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)
view.addSubview(imageView)
return view
}
The just change titleView
navigationItem.titleView = imageView
What about setting the center of your image equals to the navigationBar.center instead of setting a margin?
//assuming we already have our navigationController
let myNicelLogoWidth = 100
let myNiceLogoHeight = 50
//start positioning your logo at 0.0, 0.0
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: myNicelLogoWidth, height: myNiceLogoHeight))
imageView.contentMode = .scaleAspectFit
imageView.center = navigationBar.center //the put your image at the center
let image = UIImage(named: "myNiceLogoImage")
imageView.image = image
navigationItem.titleView = imageView
I once face with this problem, and finally i found out that the problem is the previous navigation bar title still located next to burger button, but it's invisible.
Fast solution but not sure if it's the best is to change the previous navigation bar title to empty string before show the next view controller.
Hope it's help.

Image in top background of UITableView - iOS

I can set an image to my TableView background, but the image is in the center of the view.
How can I set the image to top ?
I'm using staticTableView
let image = UIImageView(image: UIImage(named: "img.jpg"))
self.settingsTableView.backgroundView = image
self.settingsTableView.backgroundView?.frame = CGRectZero
self.settingsTableView.backgroundView?.contentMode = UIViewContentMode.ScaleAspectFit
If you're using a static table and theres no chance of changing it you might want to take an approach like this:
override func viewDidLoad() {
super.viewDidLoad()
//Create the UIImage
let image = UIImage(named: "testing")
//Create a container view that will take all of the tableView space and contain the imageView on top
let containerView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: self.view.bounds.width, height: self.view.bounds.height))
//Create the UIImageView that will be on top of our table
let imageView = UIImageView(frame: CGRect(x: 0.0, y: 0.0, width: self.view.bounds.width, height: image!.size.height))
//Set the image
imageView.image = image
//Clips to bounds so the image doesnt go over the image size
imageView.clipsToBounds = true
//Scale aspect fill so the image doesn't break the aspect ratio to fill in the header (it will zoom)
imageView.contentMode = UIViewContentMode.ScaleAspectFit
containerView.addSubview(imageView)
self.tableView.backgroundView = containerView
}
Make the cells or the headers transparent as you wish. I don't know how your UI should work. This method WON'T scroll the imageView but you can simply do it in the scrollView delegate method. Let me know if you need it to scroll and I'll help you out

Resources