Swift Add Image to UIImageView from User Tap - ios

I have a ScrollView with an ImageView inside.
Here a user can select a point on the image and it will print out the coordinates.
I'm also trying to add an image ("pin") to the tapped coordinate but am unsure how to...
// MARK: - Outlets
#IBOutlet weak var containerView: UIView!
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var sharkImage: UIImageView!
// MARK: - View Did Load
override func viewDidLoad() {
super.viewDidLoad()
scrollView.minimumZoomScale = 1.0
scrollView.maximumZoomScale = 6.0
scrollView.delegate = self
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapAction))
self.sharkImage.isUserInteractionEnabled = true
self.sharkImage.addGestureRecognizer(tapGestureRecognizer)
}
// MARK: - Scroll View
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return sharkImage
}
// MARK: - Functions
func tapAction(sender: UITapGestureRecognizer) {
// Get points for the UIImageView
let touchPoint = sender.location(in: self.sharkImage)
print(touchPoint)
// Get points from the image itself
let z1 = touchPoint.x * (sharkImage.image?.size.width)! / sharkImage.frame.width
let z2 = touchPoint.y * (sharkImage.image?.size.height)! / sharkImage.frame.height
print("Touched point (\(z1), \(z2)")
}

In your tapAction:
let pin = UIImageView(frame: CGRect(x: touchPoint.x - 20, y: touchPoint.y - 20, width: 40, height: 40))
pin.image = UIImage(named: "pin")
sharkImage.addSubview(pin)
So what I´m doing is adding a new UIImageView with the x and y from touchPoint.x and touchPoint.y into your current sharkImage.

Related

How to add person image in image frame only?

Any one know how to add person image in frame in swift. I have tried here its video. Right now i did add frame imageview and above i have added person imageview. but i don't know how to add person imageview only in blur part only
https://drive.google.com/open?id=18nchB2wh5hqjlcGqxHrsDbtpe9VkEoKd
class ViewController: UIViewController {
#IBOutlet weak var imgFrame : UIImageView!
#IBOutlet weak var imgPerson : UIImageView!
#IBOutlet weak var scrollView : UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.imgPerson.isUserInteractionEnabled = true
let gestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePan))
self.imgPerson.addGestureRecognizer(gestureRecognizer)
scrollView.minimumZoomScale = 1.0
scrollView.maximumZoomScale = 10.0//maximum zoom scale you want
scrollView.zoomScale = 1.0
scrollView.delegate = self
}
#IBAction func handlePan(_ gestureRecognizer: UIPanGestureRecognizer) {
if gestureRecognizer.state == .began || gestureRecognizer.state == .changed {
let translation = gestureRecognizer.translation(in: self.view)
// note: 'view' is optional and need to be unwrapped
gestureRecognizer.view!.center = CGPoint(x: gestureRecognizer.view!.center.x + translation.x, y: gestureRecognizer.view!.center.y + translation.y)
gestureRecognizer.setTranslation(CGPoint.zero, in: self.view)
}
}
}
extension ViewController : UIScrollViewDelegate {
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return imgPerson
}
}

UIPageControl and UIScrollView not scrolling

I'm having a relatively simple UIViewController with a UIScrollView that's taking relatively half the screen and a UIImageView placed inside the UIScrollView that's the exact same size as the UIScrollView.
On top of the UIImageView there's a UIPageControl. The point is have a horizontal scrolling and present an image like a slider based on the amount of images in an array. The problem is that the scroll view is not scrolling and I don't know why.
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var pageControl: UIPageControl!
let imagelist = ["3.jpg", "1.jpg", "2.png", "4.png", "5.png"]
override func viewDidLoad() {
super.viewDidLoad()
scrollView.delegate = self
configurePageControl()
for i in stride(from: 0, to: imagelist.count, by: 1) {
var frame = CGRect.zero
frame.origin.x = self.scrollView.frame.size.width * CGFloat(i)
frame.origin.y = 0
frame.size = self.scrollView.frame.size
scrollView.isPagingEnabled = true
scrollView.isScrollEnabled = true
let myImage:UIImage = UIImage(named: imagelist[i])!
let bgColorFromImage = myImage.averageColor
imageView.image = myImage
imageView.contentMode = UIViewContentMode.scaleAspectFit
imageView.frame = frame
scrollView.backgroundColor = bgColorFromImage
scrollView.addSubview(imageView)
}
self.scrollView.contentSize = CGSize(width: self.scrollView.frame.size.width * CGFloat(imagelist.count), height: self.scrollView.frame.size.height)
pageControl.addTarget(self, action: #selector(changePage), for: UIControlEvents.valueChanged)
}
func configurePageControl() {
self.pageControl.numberOfPages = imagelist.count
self.pageControl.currentPage = 0
self.pageControl.tintColor = UIColor.red
self.pageControl.pageIndicatorTintColor = UIColor.black
self.pageControl.currentPageIndicatorTintColor = UIColor.green
self.imageView.addSubview(pageControl)
}
#objc func changePage() {
let x = CGFloat(pageControl.currentPage) * scrollView.frame.size.width
scrollView.setContentOffset(CGPoint(x: x,y :0), animated: true)
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let pageNumber = round(scrollView.contentOffset.x / scrollView.frame.size.width)
pageControl.currentPage = Int(pageNumber)
}
This is what the UIStoryboard looks like:
Inside the for loop you use the same object of imageView , you only set the frame and the image
imageView.frame = frame
imageView.image = myImage
but you have to create a new instance of the UIImageView
//
Suppose you have a scrollView in IB with top , leading and trailing constraints to the superView , and a height of say 200 , you can add imageViews dynamically like this
class ViewController: UIViewController {
#IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
for i in 0..<10 {
let f = CGRect(x: CGFloat(i) * scrollView.frame.width, y: 0, width: scrollView.frame.width, height: scrollView.frame.height)
let imgV = UIImageView(frame: f)
imgV.image = UIImage(named: "re-fuel.png")
scrollView.addSubview(imgV)
}
scrollView.contentSize = CGSize(width: CGFloat(10) * scrollView.frame.width, height: scrollView.frame.height)
}
}
Result
The problem is that the scroll view itself is positioned with autolayout. Once you do that, you cannot set the contentSize to make the scroll view scrollable. You must use internal constraints to configure the content size.

Zoom array of images in UIScrollView

How i can zoom array of images? Now i can zoom image as a .gif
My code:
class ScrollImageViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var scrollImage: UIScrollView!
private var imageView: UIImageView!
var imagesArray = [String]()
override func viewDidLoad() {
super.viewDidLoad()
self.scrollImage.minimumZoomScale = 1.0
self.scrollImage.maximumZoomScale = 5.0
for i in 0..<imagesArray.count {
imageView = UIImageView()
imageView.sd_setImage(with: URL(string: imagesArray[i]))
imageView.contentMode = .scaleAspectFit
let xPosition = self.view.frame.width * CGFloat(i)
imageView.frame = CGRect(x: xPosition, y: 0, width: self.scrollImage.frame.width, height: self.scrollImage.frame.height)
scrollImage.contentSize.width = scrollImage.frame.width * CGFloat(i + 1)
scrollImage.addSubview(imageView)
}
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return imageView
}
}
I tried lesson from raywenderlich, but they did not help me :(
I want to get result like a AirBnB or example:
Scrolling once and zoom in, zoom out, scrolling twice - zoom in, zoom out and so on
You can check below framework
https://github.com/zvonicek/ImageSlideshow
It has a FullScreenSlideshowViewControllerclass which can be used for your purpose, also it can be customised.

How should i use UIpageControl from UIScrollView

How should I use UIpageControl from UIScrollView? I am stuck, help me out.
Here is my code please help;
class home: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var mainScrollView: UIScrollView!
#IBOutlet weak var pagecontrol: UIPageControl!
var imageArray = [UIImage]()
var pageControl : UIPageControl!
override func viewDidLoad() {
super.viewDidLoad()
mainScrollView.delegate = self
imageArray = [#imageLiteral(resourceName: "sliderImage"), #imageLiteral(resourceName: "clothing"), #imageLiteral(resourceName: "sports")]
for i in 0..<imageArray.count{
let imageView = UIImageView()
imageView.image = imageArray[i]
imageView .contentMode = .scaleToFill
let xPosition = self.view.frame.width * CGFloat(i)
imageView.frame = CGRect(x: xPosition, y: 0, width: self.mainScrollView.frame.width, height: self.mainScrollView.frame.height)
mainScrollView.contentSize.width = mainScrollView.frame.width * CGFloat(i + 1)
mainScrollView.addSubview(imageView)
}
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
Check out this answer
Things have been pretty much the same over these years:
Set your UIScrollView delegate to your view controller (which you did);
Add code for scrollViewDidScroll delegate method:
func scrollViewDidScroll(_ scrollView: UIScrollView)
{
self.pageControl.currentPage = Int(floorf(Float(scrollView.contentOffset.x / scrollView.width)))
}
Add the same in scrollViewDidEndDecelerating method:
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView)
{
self.pageControl.currentPage = Int(floorf(Float(scrollView.contentOffset.x / scrollView.width)))
}
Although, it depends on your needs - try how it works with and without each of them.

swift-Can't center UIImageView in UIScrollView with AutoLayout

I have searched many articles about UIScrollView with an UIImageView in, but all without AutoLayout info. What I have done is: place a UIScrollView in UIViewController with constraints top 10, leading 10, bottom 50, trailing 10; place a UIImageView inside of the UIScrollView with constraints top 0, leading 0, bottom 0, trailing 0. What I want is simple: let my UIImageView fit my UIScrollView when app first loaded, and let my UIImageView centered horizontally and vertically. Now I can see the image and just fit the screen nicely but the image is just at the top of UIScrollView.(notes: in this circumstance, the width of my image after being zoomed to minimum zoomScale equals to the width of UIScrollView, the height of my image after being zoom to minimum zoomScale less than the width of UIScrollView. )
I really can't move my UIImageView to center of UIScrollView vertically and can not find where I made an error. Thanks a lot.
import UIKit
class ViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func centerScrollViewContents() {
let boundsSize = scrollView.bounds.size
var contentsFrame = imageView.frame
if contentsFrame.size.width < boundsSize.width {
contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2.0
} else {
contentsFrame.origin.x = 0.0
}
if contentsFrame.size.height < boundsSize.height {
contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2.0
} else {
contentsFrame.origin.y = 0.0
}
}
override func viewDidLayoutSubviews() {
let myImage = UIImage(named: "7.jpg")
imageView.image = myImage
let weightScale = scrollView.bounds.size.width / myImage!.size.width
let heightScale = scrollView.bounds.size.height / myImage!.size.height
let minScale = min(weightScale, heightScale)
let imagew = myImage!.size.width * minScale
let imageH = myImage!.size.height * minScale
let imageRect = CGRectMake(0, 0, imagew, imageH)
imageView.frame = imageRect
scrollView.contentSize = myImage!.size
scrollView.maximumZoomScale = 1.0
scrollView.minimumZoomScale = minScale
scrollView.zoomScale = minScale
imageView.frame = imageRect
centerScrollViewContents()
}
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
return imageView
}
}
Piggy backing on pic-o-matic's answer. I had a case where I needed to center the image only if it was smaller than the scrollview frame. Using insets made for a straightforward solution.
if imageView.frame.height <= scrollView.frame.height {
let shiftHeight = scrollView.frame.height/2.0 - scrollView.contentSize.height/2.0
scrollView.contentInset.top = shiftHeight
}
if imageView.frame.width <= scrollView.frame.width {
let shiftWidth = scrollView.frame.width/2.0 - scrollView.contentSize.width/2.0
scrollView.contentInset.left = shiftWidth
}
I experienced the same problem. I found a perfect solution for me, check out this github project: https://github.com/evgenyneu/ios-imagescroll-swift
How it essentially works is as follows: it adjusts your constraints as to center the image if it is zoomed out far enough and to enable it to zoom and scroll after the width or height exceeds the respective width or height of your container.
Found it thanks to this thread: Zooming UIImageView inside UIScrollView with autolayout (obj-c and swift solution available)!
// ViewController.swift
// image-scroll-swift
//
// Created by Evgenii Neumerzhitckii on 4/10/2014.
// Copyright (c) 2014 Evgenii Neumerzhitckii. All rights reserved.
//
import UIKit
let imageScrollLargeImageName = "wallabi.jpg"
class ViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var imageConstraintTop: NSLayoutConstraint!
#IBOutlet weak var imageConstraintRight: NSLayoutConstraint!
#IBOutlet weak var imageConstraintLeft: NSLayoutConstraint!
#IBOutlet weak var imageConstraintBottom: NSLayoutConstraint!
var lastZoomScale: CGFloat = -1
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
imageView.image = UIImage(named: imageScrollLargeImageName)
scrollView.delegate = self
updateZoom()
}
// Update zoom scale and constraints
// It will also animate because willAnimateRotationToInterfaceOrientation
// is called from within an animation block
//
// DEPRECATION NOTICE: This method is said to be deprecated in iOS 8.0. But it still works.
override func willAnimateRotationToInterfaceOrientation(
toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
super.willAnimateRotationToInterfaceOrientation(toInterfaceOrientation, duration: duration)
updateZoom()
}
func updateConstraints() {
if let image = imageView.image {
let imageWidth = image.size.width
let imageHeight = image.size.height
let viewWidth = view.bounds.size.width
let viewHeight = view.bounds.size.height
// center image if it is smaller than screen
var hPadding = (viewWidth - scrollView.zoomScale * imageWidth) / 2
if hPadding < 0 { hPadding = 0 }
var vPadding = (viewHeight - scrollView.zoomScale * imageHeight) / 2
if vPadding < 0 { vPadding = 0 }
imageConstraintLeft.constant = hPadding
imageConstraintRight.constant = hPadding
imageConstraintTop.constant = vPadding
imageConstraintBottom.constant = vPadding
// Makes zoom out animation smooth and starting from the right point not from (0, 0)
view.layoutIfNeeded()
}
}
// Zoom to show as much image as possible unless image is smaller than screen
private func updateZoom() {
if let image = imageView.image {
var minZoom = min(view.bounds.size.width / image.size.width,
view.bounds.size.height / image.size.height)
if minZoom > 1 { minZoom = 1 }
scrollView.minimumZoomScale = minZoom
// Force scrollViewDidZoom fire if zoom did not change
if minZoom == lastZoomScale { minZoom += 0.000001 }
scrollView.zoomScale = minZoom
lastZoomScale = minZoom
}
}
// UIScrollViewDelegate
// -----------------------
func scrollViewDidZoom(scrollView: UIScrollView) {
updateConstraints()
}
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
return imageView
}
}
Make sure your storyboard contains a viewcontroller. In the 'View' place a 'Scroll View' and in that 'Scroll View' place an 'Image View'.
Establish top/bottom/leading/trailing constraints of 0 (or whatever value you prefer) between the 'Scroll View' and the 'View'. Then establish the same constraints between the image and the scroll view and connect them to the #IBOutlets.
This should work fine as the code changes the constraints as you zoom.
I had the same "issue".. without auto layout though. I came up with this solution(using insets to center the image).
The automaticallyAdjustsScrollViewInsets property must be set to false.
override func viewDidLoad() {
super.viewDidLoad()
//create scrollview
self.automaticallyAdjustsScrollViewInsets = false
myScrollview = MyScrollview(frame: self.view.frame)
myScrollview.alwaysBounceHorizontal = true
myScrollview.alwaysBounceVertical = true
myScrollview.delegate = self
//....
}
override func viewWillLayoutSubviews() {
//setup frame portrait and landscape
myScrollview.frame = self.view.frame
myScrollview.zoomScale = self.view.frame.width / photo.size.width
myScrollview.minimumZoomScale = self.view.bounds.width / photo.size.width
// calculate inset to center vertically
let shift = myScrollview.frame.height/2.0 - myScrollview.contentSize.height/2.0
myScrollview.contentInset.top = shift
}
override func viewDidLayoutSubviews() {
}
func scrollViewDidZoom(scrollView: UIScrollView) {
let shift = myScrollview.frame.height/2.0 - myScrollview.contentSize.height/2.0
myScrollview.contentInset.top = shift
}
I used a subclass of UIScrollView, "MyScrollview" to "see" whats going on, i think this is useful to learn about scrollview, bounds frames and content size:
//
// MyScrollview.swift
// CampingDeHooiberg
//
// Created by Andre Lam on 09-03-15.
// Copyright (c) 2015 Andre Lam. All rights reserved.
//
import UIKit
class MyScrollview: UIScrollView {
override var bounds: CGRect { willSet { println("bounds set: \(newValue) contentSize:\(self.contentSize) frame:\(self.frame)")}}
override var contentSize: CGSize { willSet { println("bounds:\(self.bounds) set contentsize:\(newValue) frame: \(self.frame)")}}
override var frame: CGRect { willSet { println("bounds: \(self.bounds) contentSize:\(self.contentSize) frame set:\(newValue)")}}
override init(frame: CGRect) {
super.init(frame: frame)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

Resources