How to add person image in image frame only? - ios

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
}
}

Related

removing auto layout constraints for a view (and subviews) but keep the same frame positions

Is there a way to 'flatten' a UIView and subviews? removing the auto layout constraints from them, but retaining their position as absolute CGRect values?
I would like to use a UIPanGestureRecogniser to move a UIView, but the autolayout is messing it up
I think Paul's comment should work. Take a look at the demo code below. When the dragging starts, I deactivate the constraints, and when it ends, the constraints are re-activated and at the same time gets new values from the new position of the dragged view.
class ViewController: UIViewController {
var top: NSLayoutConstraint?
var leading: NSLayoutConstraint?
#IBOutlet weak var viewDrag: UIView!
var panGesture: UIPanGestureRecognizer!
override func viewDidLoad() {
super.viewDidLoad()
panGesture = UIPanGestureRecognizer(target: self, action: #selector(ViewController.draggedView(_:)))
viewDrag.isUserInteractionEnabled = true
viewDrag.addGestureRecognizer(panGesture)
viewDrag.translatesAutoresizingMaskIntoConstraints = false
self.top = viewDrag.topAnchor.constraint(equalTo: self.view.topAnchor, constant: self.viewDrag.frame.origin.y)
self.leading = viewDrag.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: self.viewDrag.frame.origin.x)
self.top?.isActive = true
self.leading?.isActive = true
}
#objc func draggedView(_ sender:UIPanGestureRecognizer){
let translation = sender.translation(in: self.view)
viewDrag.center = CGPoint(x: viewDrag.center.x + translation.x, y: viewDrag.center.y + translation.y)
sender.setTranslation(CGPoint.zero, in: self.view)
if sender.state == .began {
self.top?.isActive = false
self.leading?.isActive = false
} else if sender.state == .ended {
self.top?.isActive = true
self.leading?.isActive = true
self.top?.constant = self.viewDrag.frame.origin.y
self.leading?.constant = self.viewDrag.frame.origin.x
}
}
}

How to drag and drop an image on delete icon to delete the image?

Hey guys I have just created a sample image view that can be dragged inside the view.
My Question is how to delete the image when it is dragged and placed in the delete icon?
Can anyone help with swift code
Herewith I have attached my sample program code below:
import UIKit
class ViewController: UIViewController, UIGestureRecognizerDelegate {
var Lastscale : CGFloat = 1.0
#IBOutlet weak var imgView: UIImageView!
#IBOutlet weak var deleteIcon: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(ViewController.handlePan(recognizer:)))
panGestureRecognizer.delegate = self
imgView.addGestureRecognizer(panGestureRecognizer)
imgView.isUserInteractionEnabled = true
}
#objc func handlePan(recognizer: UIPanGestureRecognizer) {
let gview = recognizer.view
if recognizer.state == .began || recognizer.state == .changed {
let translation = recognizer.translation(in: gview?.superview)
gview?.center = CGPoint(x: (gview?.center.x)! + translation.x, y: (gview?.center.y)! + translation.y)
recognizer.setTranslation(CGPoint.zero, in: gview?.superview)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Firstly, it's cleaner to use a switch statement to check for recognizer states. Also I think in this case you'd like to set the transform of the layer while the recognizer translation is changing, in this way you retain the initial frame of the view and always can animate back by setting the transform to its identity. Then if the rectangles of the button and image view layer intersect, hide the imageView, else move back. Like this:
#objc func handlePan(recognizer: UIPanGestureRecognizer) {
let gview = recognizer.view
let translation = recognizer.translation(in: gview?.superview)
switch recognizer.state {
case .began, .changed:
imgView.layer.transform = CATransform3DMakeTranslation(translation.x, translation.y, 0)
// OR
// imgView.transform = CGAffineTransform(translationX: translation.x, y: translation.y)
case .ended:
if deleteIcon.frame.intersects(imgView.layer.frame) {
animateDelete()
} else {
moveBack()
}
default:
moveBack()
}
}
func animateDelete() {
UIView.animate(withDuration: 0.3, animations: {
self.imgView.alpha = 0
}) { _ in
self.imgView.isHidden = true
}
}
func moveBack() {
UIView.animate(withDuration: 0.3) {
self.imgView.transform = CGAffineTransform.identity
}
}

How do I draw lines over an image within a ScrollView - Swift 3

I'm creating an app that allows the user to draw 2 rectangles over an image, contained within a scroll view. However, at the moment, the line does not appear to be drawn.
Here is the UIViewController that handles the drawing:
import UIKit
import CoreGraphics
import CoreData
class PhotoZoomController: UIViewController {
//Photo View's Variables
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var photoImageView: UIImageView!
#IBOutlet weak var imageViewLeadingConstraint: NSLayoutConstraint!
#IBOutlet weak var imageViewBottomConstraint: NSLayoutConstraint!
#IBOutlet weak var imageViewTopConstraint: NSLayoutConstraint!
#IBOutlet weak var imageViewTrailingConstraint: NSLayoutConstraint!
var photo: Photo!
var indicatorPoints: [CGPoint]!
var objectPoints: [CGPoint]!
var context: NSManagedObjectContext!
var brushWidth: CGFloat = 10.0;
var brushColor: CGColor = UIColor.cyan.cgColor
override func viewDidLoad() {
super.viewDidLoad()
photoImageView.image = photo.image
photoImageView.sizeToFit()
scrollView.contentSize = photoImageView.bounds.size
updateZoomScale()
updateConstraintsForSize(view.bounds.size)
view.backgroundColor = .black
}
var minZoomScale: CGFloat {
let viewSize = view.bounds.size
let widthScale = viewSize.width/photoImageView.bounds.width
let heightScale = viewSize.height/photoImageView.bounds.height
return min(widthScale, heightScale)
}
func updateZoomScale() {
scrollView.minimumZoomScale = minZoomScale
scrollView.zoomScale = minZoomScale
}
func updateConstraintsForSize(_ size: CGSize) {
let verticalSpace = size.height - photoImageView.frame.height
let yOffset = max(0, verticalSpace/2)
imageViewTopConstraint.constant = yOffset
imageViewBottomConstraint.constant = yOffset
let xOffset = max(0, (size.width - photoImageView.frame.width)/2)
imageViewLeadingConstraint.constant = xOffset
imageViewTrailingConstraint.constant = xOffset
}
#IBAction func tappedInside(_ sender: Any) {
guard let sender = sender as? UITapGestureRecognizer else {
return
}
let touch = sender.location(in: self.photoImageView)
for i in 0...3 {
if indicatorPoints[i] == CGPoint() {
indicatorPoints[i] = touch
return
}
}
for i in 0...3 {
if objectPoints[i] == CGPoint() {
objectPoints[i] = touch
return
}
}
//This part isn't finished, but it's supposed to modify previous points
}
}
extension PhotoZoomController {
I feel like this is where my problems start. I know this code runs, because I've put a print statement in here and it ran.
func drawLine(between points: [CGPoint]) {
UIGraphicsBeginImageContextWithOptions(self.photoImageView.bounds.size, false, 0)
photoImageView.image?.draw(in: self.photoImageView.bounds)
guard let context = UIGraphicsGetCurrentContext() else {
return
}
context.setLineCap(.round)
context.setLineWidth(brushWidth)
context.setStrokeColor(brushColor)
context.addLines(between: points)
context.strokePath()
UIGraphicsEndImageContext()
}
}
extension PhotoZoomController: UIScrollViewDelegate {
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return photoImageView
}
func scrollViewDidZoom(_ scrollView: UIScrollView) {
updateConstraintsForSize(view.bounds.size)
if scrollView.zoomScale < minZoomScale {
dismiss(animated: true, completion: nil)
}
}
}
This is what the UIViewController currently looks like (maybe there's something wrong with the order of views?):
Storyboard picture of the ZoomController (This UIViewController)
You are saying
UIGraphicsBeginImageContextWithOptions
and
UIGraphicsEndImageContext
and in between them, while the context exists, you draw into it.
So far, so good.
But nowhere do you say
UIGraphicsGetImageFromCurrentImageContext
Therefore, the context, containing the result of your drawing, is just thrown away.

Swift Add Image to UIImageView from User Tap

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.

Draggable UIView Swift 3

I want to be able to drag the objects on the screen, but they wont. I tried everything but still cant.
Here are the code.
func panGesture(gesture: UIPanGestureRecognizer) {
switch gesture.state {
case .began:
print("Began.")
for i in 0..<forms.count {
if forms[i].frame.contains(gesture.location(in: view)) {
gravity.removeItem(forms[i])
}
}
case .changed:
let translation = gesture.translation(in: forms[1])
gesture.view!.center = CGPoint(x: gesture.view!.center.x + translation.x, y: gesture.view!.center.y + translation.y)
gesture.setTranslation(CGPoint.zero, in: self.view)
print("\(gesture.view!.center.x)=\(gesture.view!.center.y)")
print("t;: \(translation)")
case .ended:
for i in 0..<forms.count {
if forms[i].frame.contains(gesture.location(in: view)) {
gravity.addItem(forms[i])
}
}
print("Ended.")
case .cancelled:
print("Cancelled")
default:
print("Default")
}
}
Also they have gravity. The forms are squares and circles.
Explanation:
in .began - i disable the gravity for selected form.
in .changed - i try to change the coordinates.
in .end - i enable again gravity.
ScreenShot.
Step 1 : Take one View which you want to drag in storyBoard.
#IBOutlet weak var viewDrag: UIView!
Step 2 : Add PanGesture.
var panGesture = UIPanGestureRecognizer()
Step 3 : In ViewDidLoad adding the below code.
override func viewDidLoad() {
super.viewDidLoad()
panGesture = UIPanGestureRecognizer(target: self, action: #selector(ViewController.draggedView(_:)))
viewDrag.isUserInteractionEnabled = true
viewDrag.addGestureRecognizer(panGesture)
}
Step 4 : Code for draggedView.
func draggedView(_ sender:UIPanGestureRecognizer){
self.view.bringSubview(toFront: viewDrag)
let translation = sender.translation(in: self.view)
viewDrag.center = CGPoint(x: viewDrag.center.x + translation.x, y: viewDrag.center.y + translation.y)
sender.setTranslation(CGPoint.zero, in: self.view)
}
Step 5 : Output.
It's very easy if you subclass a view:
DraggableView...
class DraggableView: UIIView {
var fromleft: NSLayoutConstraint!
var fromtop: NSLayoutConstraint!
override func didMoveToWindow() {
super.didMoveToWindow()
if window != nil {
fromleft = constraint(id: "fromleft")!
fromtop = constraint(id: "fromtop")!
}
}
override func common() {
super.common()
let p = UIPanGestureRecognizer(
target: self, action: #selector(drag))
addGestureRecognizer(p)
}
#objc func drag(_ s:UIPanGestureRecognizer) {
let t = s.translation(in: self.superview)
fromleft.constant = fromleft.constant + t.x
fromtop.constant = fromtop.constant + t.y
s.setTranslation(CGPoint.zero, in: self.superview)
}
}
Drop a UIView in your scene.
As normal, add a constraint from the left (that's the x position) and add a constraint from the top (that's the y position).
In storyboard simply simply name the constraints "fromleft" and "fromtop"
You're done.
It now works perfectly - that's it.
What is that handy constraint( call ?
Notice the view simply finds its own constraints by name.
In Xcode there is STILL no way to use constraints like IBOutlets. Fortunately it is very easy to find them by "identifier". (Indeed, this is the very purpose of the .identifier feature on constraints.)
extension UIView {
func constraint(id: String) -> NSLayoutConstraint? {
let cc = self.allConstraints()
for c in cc { if c.identifier == id { return c } }
//print("someone forgot to label constraint \(id)") //heh!
return nil
}
func allConstraints() -> [NSLayoutConstraint] {
var views = [self]
var view = self
while let superview = view.superview {
views.append(superview)
view = superview
}
return views.flatMap({ $0.constraints }).filter { c in
return c.firstItem as? UIView == self ||
c.secondItem as? UIView == self
}
}
Tip...edge versus center!
Don't forget when you make the constraints on a view (as in the image above):
you can set the left one to be either:
to the left edge of the white box, or,
to the center of the white box.
Choose the correct one for your situation. It will make it much easier to do calculations, set sliders, etc.
Footnote - an "initializing" UIView, UI "I" View,
// UI "I" View ... "I" for initializing
// Simply saves you typing inits everywhere
import UIKit
class UIIView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
common()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
common()
}
func common() { }
}
Use below code for Swift 5.0
Step 1 : Take one UIView from Storyboard, drag it into your ViewController file and Create IBOutlet of UIView.
#IBOutlet weak var viewDrag: UIView!
var panGesture = UIPanGestureRecognizer()
Step 2 : In viewDidLoad() adding the below code.
override func viewDidLoad() {
super.viewDidLoad()
let panGesture = UIPanGestureRecognizer(target: self, action:(Selector(("draggedView:"))))
viewDrag.isUserInteractionEnabled = true
viewDrag.addGestureRecognizer(panGesture)
}
Step 3 : Create func and add code to move the UIView as like below.
func draggedView(sender:UIPanGestureRecognizer){
self.view.bringSubviewToFront(viewDrag)
let translation = sender.translation(in: self.view)
viewDrag.center = CGPoint(x: viewDrag.center.x + translation.x, y: viewDrag.center.y + translation.y)
sender.setTranslation(CGPoint.zero, in: self.view)
}
Hope this will help someone.
This UIView extension makes a UIView object draggable and limits the movement to stay within the bounds of the screen.
extension UIView {
func makeDraggable() {
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
self.addGestureRecognizer(panGesture)
}
#objc func handlePan(_ gesture: UIPanGestureRecognizer) {
guard gesture.view != nil else { return }
let translation = gesture.translation(in: gesture.view?.superview)
var newX = gesture.view!.center.x + translation.x
var newY = gesture.view!.center.y + translation.y
let halfWidth = gesture.view!.bounds.width / 2.0
let halfHeight = gesture.view!.bounds.height / 2.0
// Limit the movement to stay within the bounds of the screen
newX = max(halfWidth, newX)
newX = min(UIScreen.main.bounds.width - halfWidth, newX)
newY = max(halfHeight, newY)
newY = min(UIScreen.main.bounds.height - halfHeight, newY)
gesture.view?.center = CGPoint(x: newX, y: newY)
gesture.setTranslation(CGPoint.zero, in: gesture.view?.superview)
}
}

Resources