TapGestureRecognizer not firing in swift - swift

Hi I'm having no cards to used to fixed this. Here we go.
I have this five imageview this is the declaration of first imageview but basically they have same declaration
#IBOutlet weak var first: UIImageView!{
didSet{
first.tag = 1
first.addGestureRecognizer(tapGesture())
}
}
and Then the tapGesture() method is this
private func tapGesture() -> UITapGestureRecognizer {
let tapGesture = UITapGestureRecognizer(target: self, action: Selector("iconTapped:"))
tapGesture.numberOfTapsRequired = 1
tapGesture.numberOfTouchesRequired = 1
return tapGesture
}
the action when the imageview is tapped the iconTapped() method is called, this is the code
func iconTapped(sender:UITapGestureRecognizer){
if let tag = sender.view?.tag{
processGesture(tag)
}
}
I have put all imageview userInteractionEnable to true but still not firing. Could anyone help me?
Some factor may or may not help, inside the viewdidload I update constraints and do some animation to imageview, but I'm not adding any subview programmatically

after trying so many things, I look on my view hierarchy and figure out that the parent view where my UIImageView rest userInteractionEnable is set to false(unchecked) in storyboard.
in this case the parentview is my superview, to fixed that I need to add this in viewDidLoad()
self.view.userInteractionEnabled = true
or
click the parentView in storyboard and in attributes inspector check the User Interaction Enable.
ps. sorry for silly mistake but I'll keep this question posted there might be other encountering same problem.

Related

adding a pan gesture to a subview of a UIView called from a UIViewController

I created a custom view with a subview where its frame origin x is set to the width of the parent view so that it looks like a tab sticking out of the view. (like a tab folder). The custom view is an IBOutlet in a view controller. My objective is to drag the tab to pull out the custom view like opening a panel. When I add the Pan gesture to the dragging tab, the subview, nothing happens. It works when I add it directly to the parent view. Any help would be awesome.
let pan = UIPanGestureRecognizer(target: self, action: #selector(dragView(pan:)))
pan.minimumNumberOfTouches = 1
pan.delegate = self
notesView.dragView.addGestureRecognizer(pan)
neither the func nor the delegate methods are triggered.
//MARK: - Don't forget to add UIGestureRecognizerDelegate, when you add delegate to gestureRecognizer
class ViewController: UIViewController, UIGestureRecognizerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
//MARK: set panGestureRecognizer
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(panGestureRecognizerTapped))
panGestureRecognizer.minimumNumberOfTouches = 1
//MARK: set panGestureRecognizer delegate
panGestureRecognizer.delegate = self
//MARK: Set panGestureRecognizer to view
view.addGestureRecognizer(panGestureRecognizer)
//MARK: - Add user interaction to you custom view or view
view.isUserInteractionEnabled = true
}
//MARK: when tap is happened the below attribute will be executed
#objc func panGestureRecognizerTapped() {
print("Pan Gesture Recognizer Tapped")
}
}
//The resource code is at the below link:
https://github.com/ahmetbostanciklioglu/PanGestureRecognizer.git

How can I load a website by clicking a UIImage View?

I have created a UI Image view. Is it possible for the user to click on the UI Image view and have the link pop up? If so how would I go about incorporating that? I was thinking possibly through my View Controller using Touches Began and then specifically with a tag, but I'm using Swift's Game View Controller so the Touches Began function is not working properly and won't allow me to convert my SKNODE to Game View Controller type. Any suggestions on how you would do this? Thanks
You are going to want to look at UITapGestureRecognizer. Here is an example below.
if let imageView = yourImageView {
let tap = UITapGestureRecognizer(target: self, action: #selector(self.openLink(_:)))
imageView.addGestureRecognizer(tap)
}
Here is a link if you are also wondering how to open a link in safari.
Swift Open Link in Safari
I just used a gesture recognizer and it worked perfectly
Check out this :
let recognizer = UITapGestureRecognizer(target: self, action: #selector(webViewTapped))
recognizer.delegate = self
webView.addGestureRecognizer(recognizer)
and :
#objc func webViewTapped(_ recognizer: UITapGestureRecognizer) {
if let selectedWebView = recognizer.view as? WKWebView {
selectWebView(selectedWebView)
}
}
func selectWebView(_ webView: WKWebView) {
activeWebView = webView
updateUI(for: webView)
}

Swift: addGestureRecognizer not work for stackview children

Codes:
for ... {
let view = CategoryClass.createMyClassView()
view.myLabel.text = packTitle
view.twoLabel.text = packText
view.bgCaategory.layer.cornerRadius = 30
i = i + 1
if(i == 1){
selectPackId = packId!;
view.imgSelect.image = UIImage(named: "selected")
} else {
view.imgSelect.image = UIImage(named: "select")
}
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleSendData(sender:))))
self.stackView.addArrangedSubview(view)
}
#objc func handleSendData(sender: UITapGestureRecognizer) {
print("H 1")
}
If i click on view, nothing print "H 1"
I want if i click on view, get id or another value of view
If adding isUserInteractionEnabled as suggested by Marcel still doesn't work, also make sure that every parent view in the hierarchy has a valid frame (you can check it in Debug View Hierarchy).
E.g. it happened to me to add a UIStackView into a parent UIView but the layout constraints were not correct, so I ended up having the parent UIView frame size as 0 (but the UIStackView was still visible).
If you create the UIStackView in interface builder, the isUserInteractionEnabled property is false by default. This means that the view and all it's child views won't respond to user interaction.
When you create a view in code, this property is true be default.
Add:
stackView.isUserInteractionEnabled = true
You only have to add this once, in your viewDidLoad for example.
The reason it doesn’t work is possibly a wrong method signature. The correct signature for recognizer actions is this:
recognizerAction(_ recognizer: UIGestureRecognizer)

Tap gesture on UILabel beside a UIPageControl not working

I have a UILabel on both sides of a UIPageControl, as pictured below:
I found that tapping on the sides of the UIPageControl the dot would progress, ie not on my arrows and not triggering a method of mine. But nothing else would change, so I set isUserInteractionEnabled to false on the UIPageControl.
I connected (via UITapGestureRecognizer) another UILabel above and it launches a method fine.
However the UILabels, beside the UIPageControl, will not work. NOTE: I do have isUserInteractionEnabled set to true on this element. (I even temporarily changed the element to a UIButton and it wouldn't work either - so I reverted back to my UILabel.)
So, is there a way to add a UILabel to the side of a UIPageControl that gets triggered? Alternately, can the invisible objects (while tapping on the left or right of the UIPageControl - like in my second sentence) be connected to a custom method?
UPDATE:
I've added another separate modal (same title label, buttons, but no collection view and no page control). Again it won't respond when I press the label in the centre, but I temporarily am using the title label which responses and launches my method fine.
Can anyone say why?
I solved the issue!
I was declaring most variables - as well as the UILabel - in closures blocks, at the top of the class, like below:
let myLabel: UILabel = {
{
let view = UILabel()
view.translatesAutoresizingMaskIntoConstraints = false
view.isUserInteractionEnabled = true
view.textColor = UIColor.blue
return view
}
Within this closure I had view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(doMyLabelMethod(_:)))) and view.isUserInteractionEnabled = true, when I moved them out of the closure and placed them directly above addSubview(myLabel) it fired fine.
So variable-closures are good to contain many dressing, but not gesture recognizers!

How do I pass view as an argument (swift)

I'm trying to move my fully functioning swipe gesture code into a view model to clean up the view controller but the code uses a lot of self and view references, so I suppose I need to pass along the view or UIView.self as an argument when calling the function. Can't get it to work though. Tried:
vm.swipeCode(myView: self.view)
func swipeCode(myView: UIView) {...
But it crashes. After some research I also tried variations of inout and & but to no avail. Here's the full swipe code (it references back to the view controller but I will move those as well when things start working :) )
var myVC = RecipesViewController()
func swipeCode(myView: UIView) {
//SWIPE RIGHT
let swipingRight = UISwipeGestureRecognizer()
swipingRight.addTarget(self, action: #selector(myVC.swipeRight))
swipingRight.direction = .right
swipingRight.delegate = self as? UIGestureRecognizerDelegate
swipingRight.cancelsTouchesInView = false
myView.isUserInteractionEnabled = true
myView.addGestureRecognizer(swipingRight)
//// ALLOW SWIPE LEFT ////
let swipingLeft = UISwipeGestureRecognizer()
swipingLeft.addTarget(self, action: #selector(myVC.swipeLeft))
swipingLeft.direction = .left
swipingLeft.delegate = self as? UIGestureRecognizerDelegate
swipingLeft.cancelsTouchesInView = false
myView.isUserInteractionEnabled = true
myView.addGestureRecognizer(swipingLeft)
}
The crash is probably because of these two lines:
swipingRight.addTarget(self, action: #selector(myVC.swipeRight))
swipingLeft.addTarget(self, action: #selector(myVC.swipeLeft))
You passed myVC.swipeLeft as the action, but self as the target, so the gesture recogniser will try to find a swipeLeft method in self, which doesn't exist.
You should always ensure that the action is a member of the target:
swipingRight.addTarget(myVC, action: #selector(myVC.swipeRight))
swipingLeft.addTarget(myVC, action: #selector(myVC.swipeLeft))
You should simply make a UIView or UIViewController inherited class instead if your methods use a lot of self then simply make your controllers or views of that class.
class CustomViewController:UIViewController {
func swipeCode(myView: UIView) {
// Your code here
}
// Any other methods your code might need
}
class RecipesViewController:CustomViewController {
// Whatever else your view controller is made from
}
Or if your code swiping works in every view controller you could also extends the UIViewController to add those functionnalities