Reputation: 23
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
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