well before i ask this i try the other solutions and it didn't work
this is my code
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture = UITapGestureRecognizer(target: self, action: "didTouchBoard:")
view.addGestureRecognizer(tapGesture)
tapGesture.cancelsTouchesInView = true
}
when i click anywhere it will hide the keyboard if exist , but if i click on tableviewcell or collectionviewcell , it won't click
i try this tapGesture.cancelsTouchesInView , but not work
If you want table view to receive touch, then change tapGesture.cancelsTouchesInView
tapGesture.cancelsTouchesInView = false
You have to add the UITextFeildDelegate methods to enable and disable tap gesture in the view
declare tapGesture outside the view did load method
let tapGesture = UITapGestureRecognizer(target: self, action: "didTouchBoard:")
implement the following methods
func textFieldDidBeginEditing(textField: UITextField) {
self.view.addGestureRecognizer(self.tapGesture) }
func textFieldDidEndEditing(textField: UITextField) {
self.view.removeGestureRecognizer(self.tapGesture)
}
i think that might work for you
Related
I created a custom keyboard screen on tvOS.
If possible, tap on UITextField as it is, I want to transition to the custom keyboard view.
But tapping the UITextField always displays the system keyboard.
What should I do now?
1) Make the view controller implement this delegate: UITextFieldDelegate
class YourViewController: UIViewController, UITextFieldDelegate {
// ...
yourTextField.delegate = self
// ...
}
2) Return false in textFieldShouldBeginEditing, so the text field doesn't respond and the keyboard doesn't open. Instead, open yours or do whatever you want.
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
// HERE, open your keyboard or do whatever you want
return false
}
textField.inputView = UIView()
class YourViewController: UIViewController,UITextFieldDelegate { }
First set your delegate for textfieldtextField.delegate = self, Then
func textFieldDidBeginEditing(_ textField: UITextField) {
textField.addTarget(self, action: #selector(gettextFieldFunction), for: UIControlEvents.touchDown)
}
I have two ViewControllers.
On VC1 I have search criteria and on VC2 I have the search results. If you want to go from VC2 to VC1 the VC2 is dismissed.
On VC1 I have an NSButton(style Check, type Switch) which by default I want it to be in ON state. The purpose of the NSButton is to include photos in the results.
If the user unchecks the button and presses search, it will go on to VC2 showing the search results without photos.
BUT when the user goes back to VC1 for a new search that's where the unwanted behaviour occurs:
The NSButton is unchecked(i want it to be checked by default, every time the user is at the VC1. Also, the button is nil.
Why is this happening, and how can i make it the button box to be ticked everytime the VC2 is dismissed?
I tried enabling it and setting it to ONState but as its nil it would crash.
To set a state every time your controller opens use the method
-(void)viewWillAppear
To let viewControllers communicate with each other you can implement delegates. Here is a pretty good tutorial: Link
Another approach is to communicate with Notifications -> Link
Or you can set values on methods like prepareForSegue - depending on what you use to imstantinate your controllers.
I have managed to make it perform the way I want it by adding
switch.state=1
just before the segue from VC1 to VC2 is performed.
However, I don't think this is the most elegant solution as the button is still nil.
UPDATE:
I have figured out that the issue occurs as when it goes from VC1 to VC2 the VC1 becomes nil, when the VC2 is dismissed it becomes nil as well. Hence the crash. One solution is to use delegates.
VC1:
class FirstViewController: UIViewController,SecondViewControllerProtocol {
#IBOutlet var firstName: UITextField!
#IBOutlet var lastName: UITextField!
#IBOutlet var subscribeSwitch: UISwitch!
#IBAction func goToSecondVC(_ sender: Any) {
let viewController = self.storyboard?.instantiateViewController(withIdentifier: String(describing: SecondViewController.self)) as! SecondViewController
viewController.delegate = self
self.present(viewController, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func dismissViewController() {
if let viewController = self.storyboard?.instantiateViewController(withIdentifier: "SecondViewController"){
subscribeSwitch.isOn=true
}
}
}
VC2:
protocol SecondViewControllerProtocol {
func dismissViewController()
}
class SecondViewController: UIViewController {
var delegate:SecondViewControllerProtocol!
#IBAction func goBackToFirstVC(_ sender: Any) {
self.dismiss(animated: true) {
self.delegate!.dismissViewController()
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I want to change the UIBarButtonItem display, I can add a button without problem, but the added UIBarButtonItem doesn't do any action. Any one please help?
let leftBarButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.action, target: self, action: #selector(sayHello))
func sayHello() {
print("Hello")
}
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.setLeftBarButton(leftBarButton, animated: true)
}
I am using a custom table view cell. This cell has a label with outlet called chatNameLabel. Adding a UILongPressGestureRecognizer to this label never fires the associated event.
I'm guessing that the problem is that the UILabel is in a TableView and that the table/cell view is intercepting the taps. Can I do something about this?
All I want to do is perform some custom action when a UILabel is long pressed!
I believe this was answered in Objective-C however I am not familiar with the language at all and new to swift.
Here's the code I'm using:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if let sessions = self.chatSessions where sessions.indices.contains(indexPath.row) {
let session = sessions[indexPath.row]
if session.sessionId == nil {
//DO A THING
}
// existing session id (existing chat)
else {
let cell = tableView.dequeueReusableCellWithIdentifier("ChatListCell", forIndexPath: indexPath) as! ChatListTableViewCell
cell.tag = indexPath.row
if(session.unreadChats) {
cell.indicatorImageView.tintColor = AppStyles.sharedInstance.indicatorActive
}
else{
cell.indicatorImageView.hidden = true
}
//Want to do gesture on this label below cell.chatNameLabel
cell.chatNameLabel.text = session.chatName
... Some more code not needed for question below this
Your class needs implement UIGestureRecognizerDelegate , then the below code should work.
myLabel.userInteractionEnabled = true
let tap: UILongPressGestureRecognizer = UILongPressGestureRecognizer(
target: self, action: #selector(tappedTheLabel))
tap.minimumPressDuration = 0.5
tap.delaysTouchesBegan = true
myLabel.addGestureRecognizer(tap)
tap.delegate = self
}
func tappedTheLabel(sender: UITapGestureRecognizer)
{
print("label hit \(sender)")
}
I have a tableView, and when the user taps a cell, it opens an alert box with the options "Close" and "Search". The handler for "Search" is shown below as func searchSongAction.
This presents a new viewcontroller (embedded in a Nav Bar) that searches the song online. In this new viewcontroller, Search, there are 2 functions: one searches the song currently playing and the other searches the song that the user asked to search from the tableView alert.
I am trying to pass the data from the cell into the Search class, but I keep coming up short. I feel like what I have is correct, but that is obviously not he case.
Any ideas?
Ask me if you need any more information.
History.swift
func searchSongAction(alert: UIAlertAction!) {
let vc = self.storyboard?.instantiateViewControllerWithIdentifier("Search") as! Search
let navigationController = UINavigationController(rootViewController: vc)
self.presentViewController(navigationController, animated: true, completion: nil)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let destinationNavigationController = segue.destinationViewController as! UINavigationController
let targetController = destinationNavigationController.topViewController as! Search
targetController.searchType = "Previous"
targetController.songNowText = self.songToSearch
targetController.artistNowText = self.artistToSearch
}
Search.swift
class Search: UIViewController {
var songNowText = ""
var artistNowText = ""
var searchType = ""
override func viewDidLoad() {
super.viewDidLoad()
if searchType == "Previous" {
searchSongPrevious()
} else {
searchSongNow()
}
}
}
You're not actually performing a Segue from your searchSongAction: function, so I'm guessing that prepareForSegue:sender: isn't actually being called and therefore the setup is not running.
Try assigning searchType, songNowText and artistNowText on vc inside of searchSongAction::
func searchSongAction(alert: UIAlertAction!) {
let vc = self.storyboard?.instantiateViewControllerWithIdentifier("Search") as! Search
//Setup the properties
vc.searchType = "Previous"
vc.songNowText = self.songToSearch
vc.artistNowText = self.artistToSearch
let navigationController = UINavigationController(rootViewController: vc)
self.presentViewController(navigationController, animated: true, completion: nil)
}
As a side note, typically you'll want to call super's implementation of a function when overriding it (you have neglected to do this in prepareForSegue:sender:)