I have some Class extended from base class (MSC_CLItem) like this:
class MSC_CLItem
{
var Type:MSC_CustomListType!
func RenderUI(Point:CGPoint) -> UIView
{
return UIView(frame: CGRect.zero)
}
}
Each extended class must to override RenderUI func to generate itself. All of the extended objects will be added in UIScrollView. Now my problem is:
An uiimageview with TapGesture inside of custom view not detect action. For example my class is:
class MSC_CLItem_Tizer : MSC_CLItem
{
var Title:String!
var Video:MSC_CLItem_TizerVideo!
var Detail:MSC_CLItem_TizerDetail!
private init(title:String!)
{
super.init()
self.Title = title
super.Type = .Tizer
}
override func RenderUI(Point:CGPoint) -> UIView
{
let v = UIImageView()
v.backgroundColor = UIColor.yellowColor()
let screenSize: CGRect = UIScreen.mainScreen().bounds
v.frame.size = CGSize(width: screenSize.width - 10, height: CGFloat(160))
v.frame.origin = Point
let vid = UIImageView()
vid.image = UIImage(named: "default")
vid.backgroundColor = UIColor.grayColor()
vid.contentMode = .ScaleAspectFill
vid.af_setImageWithURL(NSURL(string: "Image HTTP url")!)
vid.frame.size = v.frame.size
vid.frame.origin = CGPoint(x: 0, y: 0)
vid.clipsToBounds = true
vid.userInteractionEnabled = true
v.userInteractionEnabled = true
let tapRecognizer = UITapGestureRecognizer(target: self, action: Selector("imageTapped:"))
vid.addGestureRecognizer(tapRecognizer)
v.addSubview(vid)
}
func imageTapped(gestureRecognizer: UITapGestureRecognizer) {
//Not detected to here
}
}
And when I tap on image the following error occurred:
NSForwarding: warning: object 0x7c8cc830 of class 'MSC_CLItem_Tizer' does not implement methodSignatureForSelector: -- trouble ahead
Unrecognized selector -[MSC_CLItem_Tizer imageTapped:]
I'm very confused of which section of my code is wrong?
Thank you
You must declare the super class as NSObject
class MSC_CLItem : NSObject
{
......
}
let tapRecognizer = UITapGestureRecognizer(target: self, action: Selector("imageTapped:"))
tapGesture.numberOfTouchesRequired = 1;
tapGesture.numberOfTapsRequired = 1;
vid.addGestureRecognizer(tapRecognizer)
v.addSubview(vid)
self.view.addSubview(v)
For more details
Does not implement methodSignatureForSelector: — trouble ahead
Got Unrecognized selector -replacementObjectForKeyedArchiver: crash when implementing NSCoding in Swift [Xcode 6 GM]
I guess here can be a problem. Write this line without ":"
let tapRecognizer = UITapGestureRecognizer(target: self, action: Selector("imageTapped"))
Related
Tap gesture event not gettint called. I may be doing something wrong, but please have a look (I tried adding recognizer to self.view but still no luck) :
LoginViewController
class LoginViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let container = UIView()
container.heightAnchor.constraintEqualToConstant(50).active = true
let myVC1 = MyViewController()
let myVC2 = MyViewController()
let myVC3 = MyViewController()
let myVC4 = MyViewController()
let myStackView = UIStackView(arrangedSubviews: [myVC1.view, myVC2.view, myVC3.view, myVC4.view])
myStackView.spacing = 10
myStackView.alignment = .Fill
myStackView.distribution = .EqualSpacing
container.addSubview(myStackView)
view.addSubview(container)
}
}
MyViewController
class MyViewController: UIViewController, UIGestureRecognizerDelegate {
let ImageView = UIImageView()
override func viewDidLoad() {
super.viewDidLoad()
ImageView.backgroundColor = UIColor.blueColor()
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(pressedSocialMediaItem(_:)))
tapGestureRecognizer.delegate = self
tapGestureRecognizer.numberOfTapsRequired = 1
ImageView.userInteractionEnabled = true
ImageView.addGestureRecognizer(tapGestureRecognizer)
view.addSubview(ImageView)
}
func pressedSocialMediaItem(sender : UITapGestureRecognizer) {
print("PRESSED ! ")
}
}
I suggest using MyViewController.pressedSocialMediaItem, so your code should work like this.
class MyViewController: UIViewController, UIGestureRecognizerDelegate {
let ImageView = UIImageView()
override func viewDidLoad() {
super.viewDidLoad()
ImageView.backgroundColor = UIColor.blueColor()
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(MyViewController.pressedSocialMediaItem(_:)))
tapGestureRecognizer.delegate = self
tapGestureRecognizer.numberOfTapsRequired = 1
ImageView.userInteractionEnabled = true
ImageView.addGestureRecognizer(tapGestureRecognizer)
view.addSubview(ImageView)
}
func pressedSocialMediaItem(sender : UITapGestureRecognizer) {
print("PRESSED ! ")
}
}
I have tested the following on my machine and it works:
import UIKit
class ViewController: UIViewController, UIGestureRecognizerDelegate {
#IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
imageView.backgroundColor = UIColor.blueColor()
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.pressedSocialMediaItem(_:)))
tapGestureRecognizer.delegate = self
tapGestureRecognizer.numberOfTapsRequired = 1
imageView.userInteractionEnabled = true
imageView.addGestureRecognizer(tapGestureRecognizer)
view.addSubview(imageView)
}
func pressedSocialMediaItem(sender : UITapGestureRecognizer) {
print("PRESSED ! ")
}
}
Okey, so I got it working somehow. All I need to do was to add view controllers inside my LoginViewController like so:
self.addChildViewController(myVC1)
Instead of using view.addSubview(container)
Notice: I'm not sure it is the correct way of doing this, and please comment if it's not. Meanwhile it solves my problem.
Is there any way i can pass parameters with UITapGestureRecognizer?
I've seen this answered for objective-c but couldn't find an answer for swift
test.userInteractionEnabled = true
let tapRecognizer = UITapGestureRecognizer(target: self, action: Selector("imageTapped4:"))
// Something like text.myParamater
test.addGestureRecognizer(tapRecognizer)
And then receive myParameter under func imageTapped4(){}
One approach would be to subclass UITapGestureRecognizer and then set a property, I've posted an example below. You could also do some check on the sender and check if equal to some tag, class, string, e.t.c
class ViewController: UIViewController {
#IBOutlet weak var label1: UILabel!
#IBOutlet weak var image: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
image.userInteractionEnabled = true;
let tappy = MyTapGesture(target: self, action: #selector(self.tapped(_:)))
image.addGestureRecognizer(tappy)
tappy.title = "val"
}
func tapped(sender : MyTapGesture) {
print(sender.title)
label1.text = sender.title
}
}
class MyTapGesture: UITapGestureRecognizer {
var title = String()
}
There are lots of examples on SO, have a look, good luck.
For Swift 4
In Viewdidload
let label = UILabel(frame: CGRect(x: 0, y: h, width: Int(self.phoneNumberView.bounds.width), height: 30))
label.textColor = primaryColor
label.numberOfLines = 0
label.font = title3Font
label.lineBreakMode = .byWordWrapping
label.attributedText = fullString
let phoneCall = MyTapGesture(target: self, action: #selector(self.openCall))
phoneCall.phoneNumber = "\(res)"
label.isUserInteractionEnabled = true
label.addGestureRecognizer(phoneCall)
Function as
#objc func openCall(sender : MyTapGesture) {
let number = sender.phoneNumber
print(number)
}
Write Class as
class MyTapGesture: UITapGestureRecognizer {
var phoneNumber = String()
}
Follow Step Properly and make change according to your variable , button ,label . It WORKS PROPERLY
Without subclassing, you can also add the parameter in the view layer (where the gesture is attached):
let tappy = UITapGestureRecognizer(target: self, action: #selector(self.tapped(_:)))
image.addGestureRecognizer(tappy)
image.layer.setValue(title, forKey: "anyKeyName")
Later in the handler
#objc private func tapped(_ sender: UIGestureRecognizer) {
guard let title = sender.view?.layer.value(forKey: "anyKeyName") as? String else { return }
// Do something with the title
}
The best way is to determind the parameter when the func imageTapped64is fired. You can get you params via the view (take a look to #Developer Sheldon answer)
or in many other ways.
I have a common functionality of displaying a corner settings list in almost all pages of my application. I have thought of using extension to achieve this common functionality.
My Code -
I created a NSObject subclass and within it had an extension of UIViewController -
import UIKit
class viewControllerExtension: NSObject
{
}
extension UIViewController
{
func setCornerSettingsTableView()
{
let maskView = UIView()
maskView.frame = self.view.bounds
maskView.backgroundColor = UIColor.lightGrayColor()
let tableView = self.storyboard?.instantiateViewControllerWithIdentifier("cornerSettingVC") as! cornerSettingVC
addChildViewController(tableView)
tableView.view.frame = CGRectMake(maskView.frame.width-maskView.frame.width/2.5, 0,self.view.frame.width/2.5, self.view.frame.height-200)
maskView.addSubview(tableView.view)
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "dismissMaskView")
maskView.addGestureRecognizer(tap)
self.view.addSubview(maskView)
}
func dismissMaskView()
{
print("dismiss called")//function called but how to dismiss the mask View
}
}
Usage - In any view controller where I need to display i just call - setCornerSettingsTableView()
Problem - As you can see I am trying to add a tap gesture recognizer to my mask view so that whenever user taps the mask view, it removes the mask view along with the table view in it, but I am unable to achieve that.
If any alternative suggestions for this are most welcome.
extension UIViewController
{
func setCornerSettingsTableView()
{
if let theMask = self.view.viewWithTag(666) as? UIView {
return // already setted..
} else {
let maskView = UIView()
maskView.tag = 666
maskView.frame = self.view.bounds
maskView.backgroundColor = UIColor.lightGrayColor()
let tableView = self.storyboard?.instantiateViewControllerWithIdentifier("cornerSettingVC") as! cornerSettingVC
addChildViewController(tableView)
tableView.view.frame = CGRectMake(maskView.frame.width-maskView.frame.width/2.5, 0,self.view.frame.width/2.5, self.view.frame.height-200)
maskView.addSubview(tableView.view)
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "dismissMaskView")
maskView.addGestureRecognizer(tap)
self.view.addSubview(maskView)
}
}
func dismissMaskView()
{
print("dismiss called")//function called but how to dismiss the mask View
if let theMask = self.view.viewWithTag(666) as? UIView {
theMask.removeFromSuperview()
}
}
}
I am trying long press Gesture in Swift for Copy Option.
But it is not working. It is not identifying the Gesture in UiView Or UILabel either.
Below is my Code
In View DidLoad
let copyLongPress = UILongPressGestureRecognizer(target: self, action: #selector(ContactDetailController.handleLongPress(_:)))
copyLongPress.numberOfTouchesRequired = 0
copyLongPress.delegate = self
copyLongPress.minimumPressDuration=0.5
self.lblDynaMobile.addGestureRecognizer(copyLongPress)
self.lblDynaMobile.userInteractionEnabled = true
self.lblDynaDDI.addGestureRecognizer(copyLongPress)
self.lblDynaDDI.userInteractionEnabled = true
self.GeneralView.addGestureRecognizer(copyLongPress)
self.EmailView.addGestureRecognizer(copyLongPress)
self.AddressView.addGestureRecognizer(copyLongPress)
New Mothod
func handleLongPress(longPressView :UILongPressGestureRecognizer) {
let lblFont:UILabel = (longPressView.view as? UILabel)!
UIPasteboard.generalPasteboard().string = lblFont.text
}
I have added UIGestureRecognizerDelegate too in the Declaration of class
Try this, and see (it's working.)
// in viewDidLoad()
let copyLongPress = UILongPressGestureRecognizer(target: self, action: #selector(self.handleLongPress(_:)))
self.lblDynaMobile.addGestureRecognizer(copyLongPress)
func handleLongPress(_ gesture: UILongPressGestureRecognizer) {
if let lblFont = gesture.view as? UILabel {
//UIPasteboard.generalPasteboard().string = lblFont.text
}
}
I got this error message: "-[UITextView labelDragged:]: unrecognized selector sent to instance 0x7a2bf400"
Here is my code:
var upperText:UITextView = UITextView()
var lowerText:UITextView = UITextView()
private func addGestureRecognizers(){
let drag1 = UIPanGestureRecognizer(target: upperText,action: Selector("labelDragged:"))
let drag2 = UIPanGestureRecognizer(target: lowerText, action: Selector("labelDragged:"))
view.addGestureRecognizer(drag1)
view.addGestureRecognizer(drag2)
}
func labelDragged(sender : AnyObject?) {
let gesture:UIPanGestureRecognizer = sender as! UIPanGestureRecognizer
let textView:UITextView = gesture.view as! UITextView
let translation:CGPoint = gesture.translationInView(textView)
textView.center = CGPointMake(textView.center.x, textView.center.y + translation.y)
gesture.setTranslation(CGPointZero, inView: textView)
}
This is my first time posting, please help.
Thanks.
You would have to set the target to self:
target: self
I hope you need to study how to add Gesture Recognizer to any View.
private func addGestureRecognizers(){
let drag1 = UIPanGestureRecognizer(target: self,action: Selector("labelDragged:"))
let drag2 = UIPanGestureRecognizer(target: self, action: Selector("labelDragged:"))
upperText.addGestureRecognizer(drag1)
lowerText.addGestureRecognizer(drag2)
}
Replace your code with mine and it will work fine.