Detect intersection of 2 UIImageView in Swift - ios

Can you help me please to figure out why my code is not working when I try to make a colission between 2 UIImageViews ?
Here is my code:
// Creating falling objects
#objc func creating(_ timer: Timer) {
for (index, imageView) in images.enumerated() {
if imageView == nil {
let fallingObjectImageView = UIImageView(image: #imageLiteral(resourceName: "PoundImage"))
fallingObjectImageView.contentMode = .scaleAspectFill
fallingObjectImageView.clipsToBounds = true
let randomX = CGFloat(drand48()) * view.frame.maxX
fallingObjectImageView.frame = CGRect(x: randomX, y: -30, width: 50, height: 50)
view.addSubview(fallingObjectImageView)
images[index] = fallingObjectImageView
// This IF is not working (I dont know why)
if (fallingObjectImageView.frame.intersects(playerImageView.frame)) {
print("HIT HIT !")
}
break
}
}
}
And a photo:
Thanks !

Related

make UIImageView fall

I've UIImageview with its own position, after clicking that ( done with tapgesture ) I want that view to fall to ground until the position is 0. I tried making it with while loop but doesn't seem to work. any soltuions ?
var bananaView = UIImageView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
#objc func handleTap(_ sender:UITapGestureRecognizer) {
let centerPosition = bananaView.frame.origin.y
while centerPosition >= 0 {
bananaView.layer.position = CGPoint(x: 0,y : centerPosition - 1)
}
}
You set the new position (0) for it. Then you wrap the layout update inside an animation block
#objc func handleTap(_ sender:UITapGestureRecognizer) {
let centerPosition = bananaView.frame.origin.y
Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in
if bananaView.frame.origin.y - bananaView.frame.height == 0 {
timer.invalidate()
} else {
bananaView.frame.origin.y -= 1
}
}
}

Running CAEmitterLayer only once

I want to run CAEmitterLayer only once, I was thinking of stopping birthRate but I can't do it. What I want is for it to run only once when tapping on the screen. I've been trying with delegates but I can't get it to work. And could you please tell me if my code is efficient.
import UIKit
import PlaygroundSupport
class Emitter {
static func get(with image: UIImage) -> CAEmitterLayer {
let emitter = CAEmitterLayer()
emitter.emitterShape = kCAEmitterLayerLine
emitter.emitterCells = generateEmitterCells(image: image)
print("emit")
emitter.setValue(0.0, forKey: "em")
return emitter
}
static func generateEmitterCells(image: UIImage) -> [CAEmitterCell] {
var cells = [CAEmitterCell]()
let cell = CAEmitterCell()
cell.contents = image.cgImage
cell.birthRate = 0.1
cell.lifetime = 20
cell.velocity = 250
cell.emissionRange = (10 * (.pi/180))
cell.scale = 0.9
cell.scaleRange = 0.3
cell.velocityRange = 100
cells.append(cell)
print("cells")
return cells
}
}
class ViewController : UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
let view2 = UIView(frame: self.view.frame)
self.view.frame = CGRect(x: 0, y: 0, width: 320, height: 580)
super.view.backgroundColor = UIColor.white
self.view.addSubview(view2)
}
#objc func handleTap() {
rain()
}
func rain() {
let emitter = Emitter.get(with: UIImage(named: "Group 1493")!)
emitter.emitterPosition = CGPoint(x: view.frame.width / 2, y: view.frame.height + 25)
emitter.emitterSize = CGSize(width: view.frame.width, height: 2)
self.view.layer.addSublayer(emitter)
}
}
let controller = ViewController()
PlaygroundPage.current.liveView = controller.view
You could set lifetime propertie to 0 after first splash
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
emitter.lifetime = 0
}
You need to do a few things.
You need to CAEmitterLayer's beginTime: emitter.beginTime = CACurrentMediaTime()
To stop new particles birth you need to set emitter.birthRate = 0. You can delay it using GCD to create this splash effect.

Select a specify subview swift

how can i select a subview and interact with it using swift and n subview. For now i have only 3 subviews and select 3 image with for.
But for example how can I remove the subview with tag 2 after i create it?
func addSubView() {
for index in 1...3 {
let image: UIImage = UIImage(named: String(index))!
imageView = UIImageView(image: image)
imageView.tag = index
imageView.isUserInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.removeSubview))
imageView.addGestureRecognizer(tapGesture)
imageView.frame = CGRect(x: randomNumber(range: 60...300), y: randomNumber(range: 60...400), width: 50, height: 50)
print(imageView)
self.backgroundImageView.addSubview(imageView)
}
}
func removeSubview() {
}
You could write a function removeSubviewWithTag(_:) that would take a tag number as a parameter:
func removeSubviewWithTag(_ tag: Int) {
if let viewWithTag2 = backgroundImageView.viewWithTag(tag) {
viewWithTag2.removeFromSuperview()
}
}
And then call it as desired:
removeSubviewWithTag(2)
If you want to know if the function was able to find and remove a subview, you could make it return a discardable Bool result:
#discardableResult func removeSubviewWithTag(_ tag: Int) {
if let viewWithTag2 = backgroundImageView.viewWithTag(tag) {
viewWithTag2.removeFromSuperview()
return true
} else {
return false
}
}
And call it as follows:
if removeSubviewWithTag(2) {
print("Removed view")
} else {
print("unable to remove view")
}
Maybe add them to an array? Using tags is rarely the best solution.
var imageViews = [UIImageView]()
func addSubView() {
for index in 1...3 {
let image: UIImage = UIImage(named: String(index))!
imageView = UIImageView(image: image)
imageView.tag = index
imageView.isUserInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.removeSubview))
imageView.addGestureRecognizer(tapGesture)
imageView.frame = CGRect(x: randomNumber(range: 60...300), y: randomNumber(range: 60...400), width: 50, height: 50)
print(imageView)
self.backgroundImageView.addSubview(imageView)
imageViews.append(imageView)
}
}
func removeSubview(at index: Int) {
imageViews[index].removeFromSuperview()
}

Annotation(Image & Text) subviews changes position after saving

I have created a PDF based application. Firstly, I get the PDF from document directory then convert it to Images and then programmatically set all images to vertically by using UIImageView & ScrollView.
Then I set different type of annotation like sign, text etc. When I finalised it to images and convert them to PDF with good result. I get different results as shown in below images.
Screen 1: convert original image size to UIImageView Size with aspect to fit ( because i have look like this type of screen) when i have convert original size to screen size at that time i have stored image original size and its used to when i have convert images to pdf after add annotation looking in screen 2.
Screen 2. when i have finalise or convert to pdf. result look in screen 2, change annotation or sign position.
let drawImage = jotViewController.renderImage() //sign image
signImg = drawImage
gestureView = UIView(frame: CGRect(x: 50, y: 300, width: 200, height: 110))
counter = counter + 1
gestureView.tag = counter
annotationImg = UIImageView(frame: CGRect(x: 0, y: 0, width:170, height: 80))
annotationImg.image = signImg
annotationImg.layer.cornerRadius = 5.0
// gestureView.frame = annotationImg.frame
cancelBtn.frame = CGRect(x: (annotationImg.frame.minX-10), y: (annotationImg.frame.maxY-10), width: 20, height: 20)
cancelBtn.setImage(#imageLiteral(resourceName: "cancel.png"), for: .normal)
cancelBtn.addTarget(self, action: #selector(cancelBtnAction), for: .touchUpInside)
gestureView.addSubview(cancelBtn)
zoomBtn.frame = CGRect(x: (annotationImg.frame.width-10), y: (annotationImg.frame.height-10), width: 20, height: 20)
zoomBtn.setImage(#imageLiteral(resourceName: "zoom.png"), for: .normal)
gestureView.addSubview(zoomBtn)
let zoomBtnpanGesture: UIPanGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(ViewController.zoomBtnPanGesture(_:)))
zoomBtnpanGesture.minimumNumberOfTouches = 1
zoomBtnpanGesture.maximumNumberOfTouches = 1
zoomBtn.addGestureRecognizer(zoomBtnpanGesture)
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(self.handlePanGesture))
panGesture.minimumNumberOfTouches = 1
panGesture.maximumNumberOfTouches = 1
annotationImg.backgroundColor = UIColor.lightGray.withAlphaComponent(0.5)
gestureView.addGestureRecognizer(panGesture)
annotationImg.clipsToBounds = true
gestureView.addSubview(annotationImg)
for getUIImageView in pdfUIImageViewArr {
if tag==0 {
let alert = UIAlertController(title: "Alert!!", message: "Please Select Signature Page.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
present(alert, animated: true, completion: nil)
}
if getUIImageView.tag == tag && tag != 0 {
getUIImageView.addSubview(gestureView)
}
}
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(gestureViewTapped(sender:)))
tapGesture.numberOfTapsRequired = 1
gestureView.addGestureRecognizer(tapGesture)
imageViewArr.append(annotationImg)
gestureViewArr.append(gestureView)
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
#IBAction func storeAsPdfAction(_ sender: AnyObject) {
self.storeToDocumentDir()
let userObj = self.storyboard?.instantiateViewController(withIdentifier: "DocumentVC") as? DocumentVC
self.navigationController?.pushViewController(userObj!, animated: true)
}
func storeToDocumentDir(){
print(pdfImage.frame)
print(view.frame)
print(gestureView.frame)
for getTextViewLbl in textViewLabelArr{
getTextViewLbl.backgroundColor = UIColor.clear
}
gestureViewArr.removeFirst()
for gestureView in gestureViewArr {
print(gestureView.frame)
zoomBtn.isHidden = true
cancelBtn.isHidden = true
// pdfImage.addSubview(gestureView)
}
pdfUIImageViewArr.remove(at: 0)
var i = 1
for getPDFImage in pdfUIImageViewArr {
getPDFImage.frame = CGRect(x: 0, y: 0, width: pdfImage.frame.size.width, height: pdfImage.frame.size.height)
getPDFImage.frame = CGRect(x: 0, y: 0, width: pageRect.size.width, height: pageRect.size.height)
getPDFImage.contentMode = UIViewContentMode.scaleToFill
//
let getImage = self.imageWithView(getPDFImage)
let fileManager = FileManager.default
let paths = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString).appendingPathComponent("img\(i).jpg")
i += 1
let image = getImage
print(paths)
let imageData = UIImageJPEGRepresentation(image, 0.5)
fileManager.createFile(atPath: paths as String, contents: imageData, attributes: nil)
setPdfImgArr.append(getImage)
}
self.createPdfFromView(pdfImage, imageArrAdd: setPdfImgArr, saveToDocumentsWithFileName: "\((setFileName)!)")
let pdfUrl = URL(fileURLWithPath:documentsFileName)
self.setImagesInScrollView(pdfUrl)
}
Problem Solved :
By Using UIScrollView Zoom:
override func viewWillLayoutSubviews() {
self.configureZoomScale()
}
func configureZoomScale() {
var xZoomScale: CGFloat = self.scrollView.bounds.size.width / self.pdfImage.bounds.size.width
var yZoomScale: CGFloat = self.scrollView.bounds.size.height / self.pdfImage.bounds.size.height
var minZoomScale: CGFloat = min(xZoomScale, yZoomScale)
//set minimumZoomScale to the minimum zoom scale we calculated
//this mean that the image cant me smaller than full screen
self.scrollView.minimumZoomScale = minZoomScale
//allow up to 4x zoom
self.scrollView.maximumZoomScale = 4
//set the starting zoom scale
self.scrollView.zoomScale = minZoomScale
}
func viewForZooming(in scrollView: UIScrollView) -> UIView?{
return pdfFinalImage
}

UIImageView is moving back after new UIView is created

Hi I am trying to make a game using swift but am currently very stuck. My game has two buttons that move a UIImageView left and right which works perfectly although when my NSTimer calls to my animateBalls function every 2.5 seconds the UIImageView that was moved goes back to its original position. How would I be able to still be able to create a New UIView every 2.5 seconds but keep the UIIMageViews current position? Thanks for any help that you can give me, Here is my code:
import UIKit
class ViewController: UIViewController {
let speed = 10.0
#IBOutlet weak var mainBar: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
_ = NSTimer.scheduledTimerWithTimeInterval(2.5, target: self, selector: Selector("animateBalls"), userInfo: nil, repeats: true)
}
#IBAction func moveRightIsTapped(sender: AnyObject) {
if(mainBar.frame.origin.x < -158.5)
{
let xPosition = mainBar.frame.origin.x + 38.5
let yPosition = mainBar.frame.origin.y
let height = mainBar.frame.height
let width = mainBar.frame.width
mainBar.frame = CGRectMake(xPosition, yPosition, width, height)
}
}
#IBAction func moveLeftIsTapped(sender: AnyObject) {
if(mainBar.frame.origin.x > -389.5)
{
let xPosition = mainBar.frame.origin.x - 38.5
let yPosition = mainBar.frame.origin.y
let height = mainBar.frame.height
let width = mainBar.frame.width
mainBar.frame = CGRectMake(xPosition, yPosition, width, height)
}
}
#IBAction func playButtonTapped(sender: AnyObject) {
animateBalls()
}
func animateBalls() {
randomNum = Int(arc4random_uniform(1))
if(randomNum == 0)
{
let ball1 = UIView()
ball1.frame = CGRect(x: 121, y: -20, width: 20, height: 20)
ball1.layer.cornerRadius = 10
ball1.clipsToBounds = true
ball1.backgroundColor = UIColor.purpleColor()
self.view.addSubview(ball1)
UIView.animateWithDuration(speed, animations:{ ball1.frame = CGRect(x: 121, y: 705, width: ball1.frame.width, height: ball1.frame.height) })
}
if(randomNum == 1)
{
let ball2 = UIView()
ball2.frame = CGRect(x: 159, y: -20, width: 20, height: 20)
ball2.layer.cornerRadius = 10
ball2.clipsToBounds = true
ball2.backgroundColor = UIColor.greenColor()
self.view.addSubview(ball2)
UIView.animateWithDuration(speed, animations:{ ball2.frame = CGRect(x: 159, y: 705, width: ball2.frame.width, height: ball2.frame.height) })
}

Resources