Custom keyboard that mimics the default iOS "globe" button - ios

In iOS keyboards there is a globe button that if held will show a pop-up list of keyboards that the user can switch to.
However in the KeyboardViewController class, the only method I see to make a keyboard switch button is the method:
self.advanceToNextInputMode()
The problem with this is that while it allows you to create a button that if clicked will switch keyboards this method does not allow you to create a button that if you press and hold will show the list of currently enabled keyboards that the user can switch to by moving their finger to the correct entry.
How can I mimic the default iOS globe keyboard button behavior?

// Launch inputMode list above the view when long pressing or swiping up from the view,
// Advance to nextInputMode when short tapping on the view.
// Example:
[KeyboardButton addTarget:self action:#selector(handleInputModeListFromView:withEvent:) forControlEvents:UIControlEventAllTouchEvents].
(void)handleInputModeListFromView:(nonnull UIView *)view withEvent:(nonnull UIEvent *)event NS_AVAILABLE_IOS(10_0);
Swift Code
override func viewDidLoad() {
super.viewDidLoad()
// Perform custom UI setup here
self.nextKeyboardButton = UIButton(type: .system)
self.nextKeyboardButton.setTitle(NSLocalizedString("Next Keyboard", comment: "Title for 'Next Keyboard' button"), for: [])
self.nextKeyboardButton.sizeToFit()
self.nextKeyboardButton.translatesAutoresizingMaskIntoConstraints = false
self.nextKeyboardButton.addTarget(self, action: #selector(handleInputModeList(from:with:)), for: .allTouchEvents)
self.view.addSubview(self.nextKeyboardButton)
self.nextKeyboardButton.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
self.nextKeyboardButton.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
}

Related

Is there a way to disable user interaction for button embedded in the navigationBar (navigationItem.leftBarButtonItem)?

I need a button in the navigationBar but it should not be "clickable".
I have found that I can simply disable the button by setting the .isEnabled property to false, but this has a visual effect on the button (makes it appear grey and very faint) which I don't want. So is there a way to apply the isUserInteractionEnabled property to a navigation bar button?
First you should create button like this globally in your UIViewController, so later you can change isUserInteractionEnabled to true or false:
lazy var rightBarButton: UIButton = {
let button = UIButton()
button.setImage(UIImage(named: "yourAssetName"), for: .normal)
button.addTarget(self, action: #selector(closeController), for: .touchUpInside)
return button
}()
Than you should add your button as customView to your barButtonItem:
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: rightBarButton)
And when you need to disable isUserInteractionEnabled, just call:
rightBarButton.isUserInteractionEnabled = false
Hope this one will help you!

UIButton change background when tapped (programmatically)

I have a custom UIButton but I am not able to make changing background or text color based on a quick tap. If something works, it's only on long press:
buton.isUserInteractionEnabled = true
buton.setTitle("text_normal", for: .normal)
buton.setTitle("text_highlighted", for: .highlighted)
buton.setTitle("text_selected", for: .selected)
buton.setTitle("text_focused", for: .focused)
The only text I can get is "text_highlighted" after holding the button ~1 second. But nothing happens on short tap.
But the action is triggered correctly:
let tap2 = UITapGestureRecognizer(target: self, action: #selector(handleTap))
buton.addGestureRecognizer(tap2)
#objc func handleTap(sender: UITapGestureRecognizer) {
print("click")
}
What I tried:
Adding custom
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
...
which is also triggered later. And combining with tocuhesEnded didn't change the color temporarily as well (maybe it was too quick).
I can't use UIButton(type: .system) as well - it's not system styled button.
Similar as with changing text this is not working as well:
self.setTitleColor(UIColor.gray, for: .normal)
self.setTitleColor(UIColor.yellow, for: .selected)
self.setTitleColor(UIColor.yellow, for: .highlighted)
self.setTitleColor(UIColor.yellow, for: .focused)
I can see yellow only when long pressed. I am looking for something like this, but it needs to work on quick tap as well.
Custom button is modifying layoutSubviews(), but not colors. Custom button contains default image and label. Whole button has rounded corners. But overall nothing special is in there.
I am not using any storyboard or XIB - everything is in Swift 4 programatically.
The button is supposed to lead to another ViewController, but I want to see the immediate feedback on click. Something like when created from storyboard: https://youtu.be/lksW12megQg?t=3m25s - not even simple alpha change works for me right now.
check isselected property of uibutton if button is selected then change the background color of button
Jen Jose was right - there was a problem with my parent class which was 'eating up' my touches. I confirmed this when moving it to different ViewController + I had the same issue with table, which couldn't handle touch events (https://stackoverflow.com/a/9248827/1317362)
EDIT:
To be precise - this button was in a UIScrollView.
Adding scrollView.delaysContentTouches = NO; solved the issue completely.
Details: https://stackoverflow.com/a/16650610/1317362

iOS/Swift: How to implement doubletap action for backButton? [duplicate]

This question already has answers here:
on single tap UIBarButton display toast and on double tap back action need to perform
(3 answers)
Closed 4 years ago.
I'm trying to implement a custom back button for every ViewController in my app. I want it to have two actions. If the button gets single tapped, it should give toast warning. If the button gets double tapped it should go back to ViewController.
How can I achieve this for only the backbutton in swift?
Try this to Work with bar Button with single and Double Tap
/// Tap Gesture to Handle Double Tap
let tapGesture : UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: #selector(SourceVC.handleGesture(getsure:)))
tapGesture.numberOfTapsRequired = 2
/// Custom Button That With Handle two actions
let customButtonn : UIButton = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
customButtonn.setTitleColor(UIColor.blue, for: .normal)
customButtonn.setTitle("button", for: .normal)
customButtonn.addTarget(self, action: #selector(SourceVC.navButton(sender:)), for: .touchUpInside)
customButtonn.addGestureRecognizer(tapGesture)
/// Create a Custom bar Button
let navLeftButton = UIBarButtonItem()
navLeftButton.customView = customButtonn
/// Assign it to navigation Bar
self.navigationItem.leftBarButtonItem = navLeftButton
My custom Button Actions in SourceVC Class
/// Single Tap
#objc func navButton(sender:UIButton){
print("navButtonTapped Once")
}
/// Double Tap
#objc func handleGesture(getsure:UITapGestureRecognizer){
print("navButtonTapped twice")
}
Simulator Output:
Console output:
Note - Doing this will move default back occur with the bar and you need to design it custom way so it appear like that as Shown in Simulator output - button appear without that back image
You cannot modify the actions and behavior for BackBarButtonItem, what you can do is create a your own UIBarButtonObject and assign it as your leftBarButtonItem while giving it your own selector
One thing to note is that this will remove the stock back button image.
Try this:
let doubleTap = UITapGestureRecognizer(target: self, action: #selector(actingFunction))
DoubleTap.numberOfTapsRequired = 2
barButton.addGestureRecognizer(doubleTap)

Swift 3 multiple gestureRecorgnizer SWRevealController

I have two gestureRecognizer I want to use.
1) Tap to close side menu (SWRevealController)
2) Tap view to dismiss keyboard
override func viewDidLoad() {
super.viewDidLoad()
menuBtn.addTarget(self.revealViewController(), action: #selector(SWRevealViewController.revealToggle(_:)), for: .touchUpInside)
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
self.view.addGestureRecognizer(self.revealViewController().tapGestureRecognizer())
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(LoginController.dismissKeyboard))
self.view.addGestureRecognizer(tap)
}
Having both of these lines together, the dismiss keyboard gestureRecognizer trumps the revealViewController. How can I combine this this use both gestures together?
Make condition in LoginController.dismissKeyboard method.
check if isKeyboard is open, then close it. Otherwise close the (SWRevealController) sidemenu.
For check keyboard is open or not you can use post notification of UIKeyboardWillShowNotification and UIKeyboardWillHideNotification methods.

How to hide iOS keyboard when side menu opens?

I am using SWRevealViewController for side menu and IQKeyboardManagerSwift for keyboard.
When I am editing content in textfield and tries to open menu, the keyboard should automatically hide but I can't manage to do so.
How should this be done?
Capture the event of the opening menu. You can do this with SWRevealViewcontroller Delegate or by simply adding an #IBAction to the menu button.
In this method call .resignFirstResponder() for the element that needs the keyboard (like a textField):
textField.resignFirstResponder()
Of course you can call this function in every element that can have a keyboard to be sure to call the right one.
Since UIBarButtonItem doesn’t inherit from UIView or expose the item’s underlying view, this isn’t as easy as adding a gesture recognizer.
One plausible solution would be to [Step 1] define a custom view for the Side Menu Icon [Step 2]add the gesture to hide keyboard to it.
//gesture:tap anywehere to dismiss the keyboard
let tap = UITapGestureRecognizer(target:self.view,action:#selector(UIView.endEditing))
tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
let customButton = UIButton(frame: CGRect.init(x: 0, y: 0, width: 20, height: 20))
customButton.setImage(UIImage(named: "menu"), for: .normal)
//hide keyboard gesture(tap gesture)
customButton.addGestureRecognizer(tap)
customButton.isUserInteractionEnabled = true
if self.revealViewController() != nil {
customButton.addTarget(self.revealViewController(), action: #selector(SWRevealViewController.revealToggle(_:)), for: .touchUpInside)
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
}
self.navigationItem.leftBarButtonItem?.customView = customButton
Please accept as answer if it works.(Worked for me)

Resources