IOS Swift TextView UITapGestureRecognizer with tab to move cursor - ios

i used default keyboard and custom keyboard
if textview touch event when custom keyboard is showing, change to default keyboard
class ReplyPage: UIViewController ,UITextViewDelegate,EmojiKeyboardDelegate,UIGestureRecognizerDelegate{
#IBOutlet weak var replyArea: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
replyArea.delegate=self
emojiView.delegate = self
replyPage = self
let tapTerm = UITapGestureRecognizer(target: self, action: #selector(textViewTouch))
tapTerm.delegate = self
replyArea.addGestureRecognizer(tapTerm)
more code...
}
#objc func textViewTouch(){
if isEmoji{
replyArea.inputView = nil
replyArea.reloadInputViews()
isEmoji = false
emojiButton.setImage(UIImage(named:"emoji"), for: UIControlState.normal)
}else{
replyArea.reloadInputViews()
replyArea.becomeFirstResponder()
}
}
}
this code is worked
but can't move cursor in textview
default tab is move cursor
but UITapGesture override this so can't work
how to use Both default tab and UITapGesture
Can i Listen Textview Touch without UITapGesture?
can't textViewDidBeginEditing()
TextView Tap do not call textViewDidBeginEditing after first open custom keyboard.
because First Custom Keyboard Open already call textViewDidBeginEditing

Please add protocol TextViewDelegate in your viewController .
And add
self.replyArea.delegate = self

Related

Tap gesture recognizer added to UILabel not working

I've the following code to add a gesture recognizer to a UILabel. User Interaction Enabled is ticked on for the label in the storyboard, but when I tap on the label the onUserClickingSendToken method is not being called.
class ViewController: UIViewController, MFMailComposeViewControllerDelegate {
#IBOutlet weak var tokenDisplay: UILabel!
var tapGestureRecognizer:UITapGestureRecognizer = UITapGestureRecognizer(target:self, action: #selector(onUserClickingSendToken(_:)))
override func viewDidLoad() {
super.viewDidLoad()
tapGestureRecognizer.numberOfTapsRequired = 1
tokenDisplay.addGestureRecognizer(tapGestureRecognizer)
}
func onUserClickingSendToken(_ sender: Any)
{
....
Initializing the tapRecognizer in viewDidLoad should do it, cause you were targeting self before the view was initialized
class ViewController: UIViewController, MFMailComposeViewControllerDelegate {
#IBOutlet weak var tokenDisplay: UILabel!
var tapGestureRecognizer:UITapGestureRecognizer!
override func viewDidLoad() {
super.viewDidLoad()
tapGestureRecognizer = UITapGestureRecognizer(target:self, action: #selector(onUserClickingSendToken(_:)))
tapGestureRecognizer.numberOfTapsRequired = 1
tokenDisplay.isUserInteractionEnabled = true
tokenDisplay.addGestureRecognizer(tapGestureRecognizer)
}
#objc func onUserClickingSendToken(_ sender: Any)
{
....
In general for UILabel clickable issue:
There are couple of reasons why your UILabel will not work as clickable
Make sure to mark UILabel UserInteraction true and if yourLabel is inside other view than mark that view UserInteraction true too.
yourLabel.isUserInteractionEnabled = true
Assigning self to target before the view initialisation, move your code inside viewDidLoad/awakeFromNib or after view Load
let tap = UITapGestureRecognizer(target: self, action: #selector(onClickLabel(_:)))
self.yourLabel.addGestureRecognizer(tap)
If you are adding UILabel programmatically, than you have to assign it's frame too.
yourLabel.frame = CGRect(x: 0, y: 0, width: 300, height: 20)
Super view in which your UILabel is should be large enough to fit/display label properly, if your label is inside some view than that view's height/weight should assign in a way that it cover the whole UILabel frame.
In my case this was the problem I had, I tried so many thing but at last it turns out that the view in which I had my label had fixed width, the label was displaying properly but onClick event was't working due to out of frame.
It was missing UILabel's trailing constraints, so half of the thing is not clickable.
Using same tab gesture for multiple view, you cannot use one tab gesture for more than one view or labels,use different for each UILabel.
try this:
let tap = UITapGestureRecognizer(target: self, action: #selector(onClickLabel(_:)))
self.yourLabel.isUserInteractionEnabled = true
self.yourLabel.addGestureRecognizer(tap)
let tap2 = UITapGestureRecognizer(target: self, action: #selector(onClickLabel(_:)))
self.someView.isUserInteractionEnabled = true
self.someView.addGestureRecognizer(tap2)
instead of this:
let tap = UITapGestureRecognizer(target: self, action: #selector(onClickLabel(_:)))
self.yourLabel.isUserInteractionEnabled = true
self.yourLabel.addGestureRecognizer(tap)
self.someView.isUserInteractionEnabled = true
self.someView.addGestureRecognizer(tap)
// tapGesture will work on only one element
Try changing your selector setup to:
#selector(ViewController .onUserClickingSendToken(_:).

Trouble with tap gestures

I have a tap gesture on a UIImageView within a class that extends UITableViewCell. This code should work, I don't see why it doesn't. The only thing I am iffy on is what the "target" should be - should it be the profileImage, or the overall ViewController that things are in?
#IBOutlet weak var profileImage: UIImageView!
var vc: TweetsViewController? = nil
override func awakeFromNib() {
super.awakeFromNib()
let tapGester = UITapGestureRecognizer(target: vc, action: Selector("handleTapGester:"))
tapGester.delegate = self
profileImage.addGestureRecognizer(tapGester)
}
func handleTapGester(tapGesture: UITapGestureRecognizer) {
print("*******hi*******")
vc?.performSegueWithIdentifier("showProfile", sender: nil)
}
And for the record, as this may seem like a relevant error, I initialize vc when the table cell loads.
The target should be the object that will handle the tap gesture and the handleTapGester function should be inside the object class you specified as the target, not inside the UITableViewCell subclass.
You also need to enable user interaction on the UIImageView by saying:
imageView.userInteractionEnabled = true
Why not just add a tap gesture recogniser to the view, then when called query indexPathForRowAtPoint to find out which cell is being tapped?
If you know the cell you can then determine if the UIImage is being tapped and make your call to performSegueWithIdentifier from there.
If it's tapped on a cell that you're not interested in let it fall through and be handled by the table by calling cancelsTouchesInView on the recogniser.

Dismissing the keyboard in a UIViewController

I'm running this code within a ViewController class that contains UIViewController and SettingsViewDelegate. The View Controller scene contains a text view that has a scroll bar.
#IBOutlet weak var tvEditor: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
// Hide keyboard via swipeDownGestureRecognizer.
let swipeGesture: UISwipeGestureRecognizer = UISwipeGestureRecognizer (target: self, action: "hideKeyboard")
swipeGesture.cancelsTouchesInView = false
UISwipeGestureRecognizerDirection.Down
}
func hideKeyboard() {
tvEditor.resignFirstResponder()
}
When I run my project in the iOS Simulator/device, the keyboard does not respond to a downward swipe. I change the orientation of my device to landscape, and then back to portrait, which is when the keyboard disappears. Can someone please tell me where I'm going wrong?
First, Please add swipeGesture to your viewcontroller.
And...
func hideKeyboard() {
self.view.endEditing(true)
}
It'll works fine for your project.
Hope it'll help you.

How do I activate an inputView using a UIButton in Swift?

I am attempting to have a UIDatePicker come up as a keyboard when the user hits a UIButton. I was able to get it to work with a textfield, but I don't like how the cursor is visible and the user could enter in any text if they had an external keyboard. Here is my code:
#IBAction func dateFieldStart(sender: UITextField) {
var datePickerStartView : UIDatePicker = UIDatePicker()
datePickerStartView.datePickerMode = UIDatePickerMode.Time
sender.inputView = datePickerStartView // error when sender is UIButton
}
I tried changing the sender to UIButton but it gave this error on the line that is marked above:
Cannot assign to 'inputView' in 'sender'
I have tried researching it and no one else seems to have had a problem with it. Anyone know how to trigger a UIDatePicker inputView using a UIButton or anything that might work better that the user cannot type into? Thanks!
This is years after the original question, but for anyone who may be looking for solution to this you can subclass UIButton and provide a getter and setter for the inputView property. Be sure to call becomeFirstResponder in the setter and override canBecomeFirstResponder. For example:
class MyButton: UIButton {
var myView: UIView? = UIView()
var toolBarView: UIView? = UIView()
override var inputView: UIView? {
get {
myView
}
set {
myView = newValue
becomeFirstResponder()
}
}
override var inputAccessoryView: UIView? {
get {
toolBarView
}
set {
toolBarView = newValue
}
}
override var canBecomeFirstResponder: Bool {
true
}
}
let tempInput = UITextField( frame:CGRect.zero )
tempInput.inputView = self.myPickerView // Your picker
self.view.addSubview( tempInput )
tempInput.becomeFirstResponder()
It's a good idea to keep a reference to tempInput so you can clean-up on close
I wanted to do the same thing, I ended up just overlaying a UITextField over the button and using the inputView of that instead.
Tip: set tintColor of the UITextField to UIColor.clearColor() to hide the cursor.
You can create a view for the picker off screen view and move it on screen when you need it. Here's another post on this.

Click button in a UIViewController that was loaded a subView (UIView)

I'm trying to add a UIView subview into a UIViewController, and that UIView has a UISwitch that I want the user to be able to toggle. Based on the state, a UITextField's value will toggle back and forth. Here is the subview (InitialView):
import UIKit
class InitialView: UIView {
// All UI elements.
var yourZipCodeSwitch: UISwitch = UISwitch(frame: CGRectMake(UIScreen.mainScreen().bounds.width/2 + 90, UIScreen.mainScreen().bounds.height/2-115, 0, 0))
override func didMoveToSuperview() {
self.backgroundColor = UIColor.whiteColor()
yourZipCodeSwitch.setOn(true, animated: true)
yourZipCodeSwitch.addTarget(ViewController(), action: "yourZipCodeSwitchPressed:", forControlEvents: UIControlEvents.TouchUpInside)
self.addSubview(yourZipCodeSwitch)
}
}
If I want to have it's target properly pointing at the below function, where should I either set the target or include this function? I tried:
Setting the target in the UIViewController instead of the UIView
Keeping the function in the UIView
Here's the function:
// Enable/disable "Current Location" feature for Your Location.
func yourZipCodeSwitchPressed(sender: AnyObject) {
if yourZipCodeSwitch.on
{
yourTemp = yourZipCode.text
yourZipCode.text = "Current Location"
yourZipCode.enabled = false
}
else
{
yourZipCode.text = yourTemp
yourZipCode.enabled = true
}
}
And here is where I'm loading it into the UIViewController:
// add initial view
var initView : InitialView = InitialView()
// Execute on view load
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
view.addSubview(initView)
}
Any help is much appreciated - thanks!
Yeah, the didMoveToSuperView() placement doesn't make much sense. So you're creating a random, totally unconnected ViewController instance to make the compiler happy but your project sad. Control code goes in controllers, view code goes in views.
You need in your real ViewController:
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(initView)
// Note 'self' is the UIViewController here, so we got the scoping right
initView.yourZipCodeSwitch.addTarget(self, action: "yourZipCodeSwitchPressed:", forControlEvents: .ValueChanged)
}
Also, .TouchUpInside is for UIButtons. Toggle switches are much more complicated, so their events are different. Touching up inside on a toggle switch's current setting can and should do nothing, whereas touchup inside on the opposite setting triggers the control event above. iOS does all the internal hit detection for you.

Resources