Can I handle the button click event of WKWebView from my app.
Simply I have opened a facebook login page in my WKWebView. Is it possible to handle the event of that login button from my app?
You can use the navigationDelegate of the WKWebView to listen to that action. The delegate method you should implement is:
Swift
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: #escaping (WKNavigationActionPolicy) -> Swift.Void)
{
let request = navigationAction.request; // Inspect this request to see if it's from Facebook
let policy = WKNavigationActionPolicyAllow or WKNavigationActionPolicyCancel depending if you want the request to continue firing or not
decisionHandler( policy );
}
Objective-C
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
NSURLRequest *request = navigationAction.request; // Inspect this request to see if it's from Facebook
WKNavigationActionPolicy policy = WKNavigationActionPolicyAllow or WKNavigationActionPolicyCancel depending if you want the request to continue firing or not
decisionHandler( policy );
}
I have a view controller in which I want to receive windowDidBecomeMain and windowDidResignMain events.
In viewWillApear() I set the window delegate to self.
view.window?.delegate = self
I have added an extension to my view controller that conforms to NSWindowDelegate and have implemented both methods in it thus:
extension CustomerListViewController: NSWindowDelegate
{
func windowDidBecomeMain(_ notification: Notification)
{
print("Customer list did become main")
}
func windowDidResignMain(_ notification: Notification)
{
print("Customer list did resign main")
}
}
This is not the initial window. It is opened via a menu item with a Window controller show segue.
When the window is first opened via the menu item, it does not receive windowDidBecomeMain.
When I click another window it does receive windowDidResignMain.
If I then click back into the newly opened window it does receive windowDidBecomeMain and will from that point on.
I suspect that I need to set my window delegate at a different point but don't have a clue where to do so, if that is the case.
So I'm working on a tvos app in swift and I was wondering if it's possible to disable dictation support for a custom UITextField. It doesn't really work well for it and I don't want the user to be able to do so
Did you try to use the textfield's keyboardType property? Maybe you can change the text input type, so the dictation function is automatically not shown.
Documentation: https://developer.apple.com/library/tvos/documentation/UIKit/Reference/UITextInputTraits_Protocol/index.html#//apple_ref/occ/intfp/UITextInputTraits/keyboardType
This is a Swift 4 solution based on #BadPirate's hack. It will trigger the initial bell sound stating that dictation started, but the dictation layout will never appear on the keyboard.
This will not hide the dictation button from your keyboard: for that the only option seems to be to use an email layout with UIKeyboardType.emailAddress.
In viewDidLoad of the view controller owning the UITextField for which you want to disable dictation:
// Track if the keyboard mode changed to discard dictation
NotificationCenter.default.addObserver(self,
selector: #selector(keyboardModeChanged),
name: UITextInputMode.currentInputModeDidChangeNotification,
object: nil)
Then the custom callback:
#objc func keyboardModeChanged(notification: Notification) {
// Could use `Selector("identifier")` instead for idSelector but
// it would trigger a warning advising to use #selector instead
let idSelector = #selector(getter: UILayoutGuide.identifier)
// Check if the text input mode is dictation
guard
let textField = yourTextField as? UITextField
let mode = textField.textInputMode,
mode.responds(to: idSelector),
let id = mode.perform(idSelector)?.takeUnretainedValue() as? String,
id.contains("dictation") else {
return
}
// If the keyboard is in dictation mode, hide
// then show the keyboard without animations
// to display the initial generic keyboard
UIView.setAnimationsEnabled(false)
textField.resignFirstResponder()
textField.becomeFirstResponder()
UIView.setAnimationsEnabled(true)
// Do additional update here to inform your
// user that dictation is disabled
}
I'm able to create pin's with their popup's as well as the info-light button to the right. And when tapped, the info button pops up an alert with some text and an "ok" button at the bottom. Is it now possible to add a link at the bottom of the text that will direct the user to a URL, saw wikkipedia for example in safari?
I've used the following called function to succesfully do so with a regular button in the mapview, but I can't figure out how to implement it the way I've stated above
#IBAction func webLink(sender: AnyObject) {
if let url = NSURL(string: "http://www.wikipedia.com") {
UIApplication.sharedApplication().openURL(url)
}
}
I am currently writing a tvOS app. I've been detecting and overriding the menu button with tapRecognizer to switch between storyboards and other functions. My issue is when I am on my home screen and press menu it does not exit the app. Instead it remembers the last function I used when overriding the menu button and performs that function. Any thoughts on how to clear the tapRecognizer? Or a function that will exit the app?
I'm overriding the menu button with
in Storyboard1
tapRecognizer = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(home)];
tapRecognizer.allowedPressTypes = #[[NSNumber numberWithInteger:UIPressTypeMenu]];
[self.view addGestureRecognizer:tapRecognizer];
in my home subroutine I send the user back to my home page storyboard. But from then on the menu button will not exit the app but send me back to storyboard1.
thanks,
SW
Instead of using your own gesture recognizer, override pressesBegan:
override func pressesBegan(presses: Set<UIPress>, withEvent event: UIPressesEvent?) {
if(presses.first?.type == UIPressType.Menu) {
// handle event
} else {
// perform default action (in your case, exit)
super.pressesBegan(presses, withEvent: event)
}
}
If you are using UIGestureRecognizer instead of responding to presses, all you need to do is to disable the recognizer:
tapRecognizer.enabled = NO;
So if no recognizer with UIPressTypeMenu is listening, tvOS suspends the app and displays the home screen. (I've tested this)
You have to override 2 methods to prevent exiting app by pressing Menu button.
Here is ready-to-use template:
override func pressesBegan(presses: Set<UIPress>, withEvent event: UIPressesEvent?) {
for press in presses {
switch press.type {
case .Menu:
break
default:
super.pressesBegan(presses, withEvent: event)
}
}
}
override func pressesEnded(presses: Set<UIPress>, withEvent event: UIPressesEvent?) {
for press in presses {
switch press.type {
case .Menu:
//Do some staff there!
self.menuButtonPressed()
default:
super.pressesEnded(presses, withEvent: event)
}
}
}
If you overwrite the menu button, the app won't be accepted:
EDIT: You can overwrite, but the menu button has to work as a back button to homescreen from the entry point of the app.
10.1 Details
The Menu button on the Siri Remote does not behave as expected in your
app.
Specifically, when the user launches the app and taps the Menu button
on the Siri remote, the app does not exit to the Apple TV Home screen.
Next Steps
Please revise your app to ensure that the Siri remote buttons behave
as expected and comply with the Apple TV Human Interface Guidelines.
It may be help you...
it is swift code.
let menuPressRecognizer = UITapGestureRecognizer()
menuPressRecognizer.addTarget(self, action: #selector(YourViewController.menuButtonAction(_:)))
menuPressRecognizer.allowedPressTypes = [NSNumber(integer: UIPressType.Menu.hashValue)]
self.view.addGestureRecognizer(menuPressRecognizer)
As per Apple's documentation, for custom press handling, we should override all four of these methods-
- (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(nullable UIPressesEvent *)event NS_AVAILABLE_IOS(9_0);
- (void)pressesChanged:(NSSet<UIPress *> *)presses withEvent:(nullable UIPressesEvent *)event NS_AVAILABLE_IOS(9_0);
- (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(nullable UIPressesEvent *)event NS_AVAILABLE_IOS(9_0);
- (void)pressesCancelled:(NSSet<UIPress *> *)presses withEvent:(nullable UIPressesEvent *)event NS_AVAILABLE_IOS(9_0);
This is the official documentation from XCode:
Generally, all responders which do custom press handling should
override all four of these methods.
Your responder will receive either pressesEnded:withEvent or pressesCancelled:withEvent: for each
press it is handling (those presses it received in pressesBegan:withEvent:).
pressesChanged:withEvent: will be invoked for presses that provide
an analog value
(like thumbsticks or analog push buttons)
*** You must handle cancelled presses to ensure correct behavior in
your application. Failure to
do so is very likely to lead to incorrect behavior or crashes.
SwiftUI Seekers:
I don't know how much this answer helps, but just adding available actions in SwiftUI.
YourAnyView
.onExitCommand(perform: {
print("onExitCommand")
})
.onMoveCommand { direction in
print("onMoveCommand", direction)
}
REF:
onmovecommand
onexitcommand