L. Watkins
L. Watkins

Reputation: 23

How to add an independent UIView on button press in swift?

I am trying to add UILabels and other UIView elements on button press and have them act as independent elements but I am having no luck. I can successfully add multiple labels and text fields but when i try to delete them using my gesture recognizer it will only delete the latest UIView element. My full code is posted below. There are two main bugs in my implementation as it is: Creating more than one label or text field at a time causes the gestures to not respond and I can only delete the latest UIView element. Any help is greatly appreciated!

My Model:

import Foundation
import UIKit

class QuizItem: UIViewController{

var alert = UIAlertController()
var labelCountStepper = 0
var tfCountStepper = 0
let gestureRecog = myLongPress(target: self, action: #selector(gestureRecognized(sender:)))
let moveGesture = myPanGesture(target: self, action: #selector(userDragged(gesture:)))

func createLabel(){
    var randLabel = UILabel(frame: CGRect(x: 200, y: 200, width: 300, height: 20))
    randLabel.isUserInteractionEnabled = true
    randLabel.textColor = UIColor .black
    randLabel.text = "I am a Test Label"
    randLabel.tag = labelCountStepper
    gestureRecog.quizItem = randLabel
    moveGesture.quizItem = randLabel
    randLabel.addGestureRecognizer(self.longPressGesture())
    randLabel.addGestureRecognizer(self.movePanGesture())
    topViewController()?.view.addSubview(randLabel)
    labelCountStepper = labelCountStepper+1
}

func createTextField(){
    var randTextField = UITextField(frame: CGRect(x: 200, y: 200, width: 300, height: 35))
    randTextField.isUserInteractionEnabled = true
    randTextField.backgroundColor = UIColor .lightGray
    randTextField.placeholder = "Enter your message..."
    randTextField.tag = tfCountStepper
    gestureRecog.quizItem = randTextField
    moveGesture.quizItem = randTextField
    randTextField.addGestureRecognizer(self.longPressGesture())
    randTextField.addGestureRecognizer(self.movePanGesture())
    topViewController()?.view.addSubview(randTextField)
    tfCountStepper = tfCountStepper+1
}



func longPressGesture() -> UILongPressGestureRecognizer {
    let lpg = UILongPressGestureRecognizer(target: self, action: #selector(gestureRecognized(sender:)))
    lpg.minimumPressDuration = 0.5
    return lpg
}

func movePanGesture() -> UIPanGestureRecognizer {
    let mpg = UIPanGestureRecognizer(target: self, action: #selector(userDragged(gesture:)))
    return mpg
}

@objc func gestureRecognized(sender: UILongPressGestureRecognizer){
    if(sender.state == .began){
        print("Label Tag #: \(labelCountStepper)")
        print("Text Field Tag #: \(tfCountStepper)")
        alert = UIAlertController(title: "Remove Item?", message: nil, preferredStyle: .alert)

        alert.addAction(UIAlertAction(title: "Yes", style: .default, handler: { (action) -> Void in
            self.gestureRecog.quizItem.removeFromSuperview()
        }))

        alert.addAction(UIAlertAction(title: "No", style: .cancel){(_) in

        })

        topViewController()?.present(alert, animated: true, completion: nil)
    }
}

@objc func userDragged(gesture: UIPanGestureRecognizer){
    let loc = gesture.location(in: self.view)
    moveGesture.quizItem.center = loc

}

override func viewDidLoad() {
    super.viewDidLoad()
}

func topViewController() -> UIViewController? {
    guard var topViewController = UIApplication.shared.keyWindow?.rootViewController else { return nil }
    while topViewController.presentedViewController != nil {
        topViewController = topViewController.presentedViewController!
    }
    return topViewController
}

}

My ViewController:

import UIKit

class ViewController: UIViewController {

var labelMaker = QuizItem()


@IBAction func createLabel(_ sender: UIButton) {
    labelMaker.createLabel()
}

@IBAction func createTextField(_ sender: UIButton) {
    labelMaker.createTextField()
}
override func viewDidLoad() {

}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

}

I also made two subclasses that inherit from UILongPress and UIPan Gesture Recognizers. I'll only post the LongPress because the UIPan is exactly the same - just inherits from UIPan instead of UILongPress.

import Foundation
import UIKit
class myLongPress: UILongPressGestureRecognizer{

var quizItem = UIView()

}

Upvotes: 2

Views: 1757

Answers (1)

Rajesh
Rajesh

Reputation: 960

You can achieve that by slighting changing your code as below:

@objc func gestureRecognized(sender: UILongPressGestureRecognizer){
    if(sender.state == .began){
        print("Label Tag #: \(labelCountStepper)")
        print("Text Field Tag #: \(tfCountStepper)")
        alert = UIAlertController(title: "Remove Item?", message: nil, preferredStyle: .alert)

        alert.addAction(UIAlertAction(title: "Yes", style: .default, handler: { (action) -> Void in
            let selectedView = sender.view
            selectedView?.removeFromSuperview()
        }))

        alert.addAction(UIAlertAction(title: "No", style: .cancel){(_) in

        })

        topViewController()?.present(alert, animated: true, completion: nil)
    }
}

@objc func userDragged(gesture: UIPanGestureRecognizer){
    let loc = gesture.location(in: self.view)
    let selectedView = gesture.view
    selectedView?.center = loc
}

Upvotes: 1

Related Questions