I'm working on an iPad application with UIWebView(Deployment target iOS 5.0+).
My UIWebView should do nothing when user taps emails, addresses and phone numbers.
I have a problem with phone numbers. If html page contains links like this: 555-555-5555 when user taps this link UIPopoverController appears(Add to Contacts, Copy).
I have tried next:
Switch off detection in xib file for UIWebView
webView.dataDetectorTypes = UIDataDetectorTypeNone;
call JS - document.documentElement.style.webkitTouchCallout = "none";
UIWebView delegate method shouldStartLoadWithRequest doesn't work for telephone numbers on iPad but works fine on iPhone.
Do you have any ideas?
The reason that particular phone number link isn't getting disabled is that it's not a detected phone number, it's just a regular old <a href=foo> link that happens to have a telephone link for its href attribute. Setting the dataDetectorTypes like you're doing is the the right way to disable phone number detection. So if you have phone numbers just appearing in the web page text somewhere and you want to prevent those from becoming links, keep using webView.dataDetectorTypes = UIDataDetectorTypeNone;.
If you want to disable all links that look like phone numbers you will need to execute a JavaScript after the page has finished loading. In your UIWebView's delegate's webViewDidFinishLoad method use [webView stringByEvaluatingJavaScriptFromString:] and pass in JavaScript to replace the offending links. Here's an example JavaScript that would replace all your tel style links with text elements showing the phone number instead. You might want something slightly different, or maybe you just want to remove the links from the DOM entirely.
var links = document.getElementsByTagName('a');
for (var j = 0; j < links.length; j++) {
var href=links[j].getAttribute('href');
var prefix = href.substring(0,4);
if (prefix == "tel:") {
var parentNode = links[j].parentNode;
var replacementNode = document.createTextNode(href.substring(prefix.length, href.length));
parentNode.replaceChild(replacementNode, links[j]);
}
}
Related
I'm working on a UWP app that hosts a WebView which runs in a separate process.
var webView = new Windows.UI.Xaml.Controls.WebView(WebViewExecutionMode.SeparateProcess)
This results in a behavior that if the WebView has the focus, the containing app can't regain the focus by itself by simply trying to focus on a UI element.
The app supports keyboard shortcuts which may result in different elements getting the focus, but it's not working correctly when the focus is captured by the WebView. The target element seems to be getting the focus but it seems as if the process itself is not activated (as the real focus resides in a different process I suppose...).
I'm currently trying to activate the app programmatically through protocol registration in an attempt to regain focus.
I added a declaration in the app manifest for a custom protocol mycustomprotocol coupled with the following activation overload
protected override void OnActivated(IActivatedEventArgs args)
{
if (eventArgs.Uri.Scheme == "mycustomprotocol")
{ }
}
And the following code to invoke the activation:
var result = await Windows.System.Launcher.LaunchUriAsync(new Uri("mycustomprotocol:"));
Seems to be working only on some computers, on others (not while debugging the app, only when executed unattached) instead of regaining focus the app's taskbar icon just flashes orange.
I've created a sample project showing the problem and the semi working solution here
Any insight on any of this would be great.
I can reproduce your issue. I found that when we switch the focus with the mouse, the focus can be transferred to the TextBlock. So you could solve this question through simulating mouse input.
Please use the following code to instead FocusTarget.Focus(FocusState.Programmatic).
As follows:
InputInjector inputInjector = InputInjector.TryCreate();
var infoDown = new InjectedInputMouseInfo();
// adjust your mouse position to the textbox through changing infoDown.DeltaX,infoDown.DeltaY
infoDown.DeltaX = 10; //change
infoDown.DeltaY = -150; //change
infoDown.MouseOptions = InjectedInputMouseOptions.LeftDown;
var infoUp = new InjectedInputMouseInfo();
infoUp.DeltaX = 0;
infoUp.DeltaY = 0;
infoUp.MouseOptions = InjectedInputMouseOptions.LeftUp;
inputInjector.InjectMouseInput(new[] { infoDown, infoUp });
Note: If you use the input injection APIs, you need to add inputInjectionBrokered Capabilitiy in your Package.appxmanifest.
But this Capabilitiy is a restricted Capabilitiy, you can’t publish this app in store, which can’t pass the verification.
I've been in discussions with a WebView software engineer. The problem is that the separate process still wants to own focus if you try to move the focus away from the webview. His solution is to ask the other process' web engine to give up focus with the following call:
_= webView.InvokeScriptAsync("eval", new string[] { "window.departFocus('up', { originLeft: 0, originTop: 0, originWidth: 0, originHeight: 0 });" });
You can call it before trying to change the focus to your target. I ran various tests and it works consistently.
I'm trying to initiate a call which also contains DTMF Numbers
ex:- 012345678,1*0001*000*1*1#
and i'm using the following code to initiate the call
guard let number = URL(string: "tel://" + number) else { return }
UIApplication.shared.open(number)
and then the systems shows popup to the user to make the call with the Full number also including the DTMF.
so i was wondering if it is possible that we can hide the DTMF part from that Popup ?
so the user only sees "012345678" instead of "012345678,1*0001*000*1*1#" as this DTMF numbers are secure data that he shouldn't see it.
Thanks
That's not possible, as far as I know. That popup is created by iOS itself and you have no control over it.
I have a WebView that loads an URL (say login.salesforce.com) & asks the user to login to his instance.
Now, I want to get rid of the default login screen that it shows up & want to play around with the color of the login button.
Is it possible to change the color of a button inside a website that loads in UIWebView or WKWebView?
Absolutely Yes. For this you need to have little bit knowledge of html,css and java script.
Step 1. Prepare a java script as a string like below:
let changeHtmlbuttonScript = """
var property = document.getElementById(btn);
if (count == 0) {
property.style.backgroundColor = "#FFFFFF"
count = 1;
} else {
property.style.backgroundColor = "#7FFF00"
count = 0;
}
"""
Step 2: Evaluate java script on your current webview
self.webView.evaluateJavaScript(self.changeHtmlbuttonScript)
You can do it with UIWebView if you override the resource loading with a custom NSURLProtocol, and load your own CSS instead of theirs. "evaluateJavaScript" might work as well if you wait until the page is loaded somehow (see other reply).
Most likely what you ask violates the Salesforce's terms of service, so I wouldn't do it.
If they have a REST API for something that you try to achieve, then you can provide your own UI.
I am working on a hybrid HTML5/iOS app that uses the Safari Webview. We are using AirPrint to allow the user print the contents of the webview. The problem I am having is that after the print dialog is opened, the print styles are taking affect on the screen, and even after printing is complete or canceled do not go away. This does not happen in our Windows or Android versions of the app, which use CEF and Android System Webview respectively. Print styles in those versions of the application are only applied to the print out, as expected.
Anyone have any experience using AirPrint with Safari Webview that could shed some light on a solution? I have considered just adding/removing the link tag containing the CSS with javascript before and after printing, but that feels hacky, and doesn't answer the curious question of why print styles are being applied to the screen.
Any help appreciated! Sorry there is no real way to attach code to this!
Yes, this is indeed a not expected behaviour. However, we can try to solve this using JavaScript.
Theory: When the print is done, let's reload the stylesheets. The browser will paint the page again and hopefully using screen definitions.
Practice: As we don't have a JavaScript callback after printing, you could try reload your stylesheets using the window.onfocus event, as follows:
function updateStylesheets(){
var links = document.getElementsByTagName("link");
for (var x in links) {
var link = links[x];
if (link.getAttribute("type").indexOf("css") > -1) {
link.href = link.href + "?id=" + new Date().getMilliseconds();
}
}
}
window.onfocus = updateStylesheets;
In detail, it grabs all <link> tags and appends a random number after, forcing a reload on the stylesheets.
Please let me know if that worked, I'd be glad to help.
I'm trying to post an article title and an article URL to twitter and then append the app's name to the end of the tweet. So something like
"How to grow a cactus (via #appname)" attached URL
I was having trouble figuring out how to balance the length of the title and URL to make sure that the tweet doesn't exceed 140 characters. So if the URL is really long, cut some of the article title off so it can be under 140 characters.
Looking at Twitter's guidelines for SLComposeViewController they state this part:
Note that the methods for setting initial content respond with Boolean values; this allows you, the developer, to not have to worry about the current count of characters in the body of the Tweet that you are initializing. If the method returns YES, there was enough room to add the content. If the method returns NO, the content you attempted to add would result in a Tweet longer than 140 characters. The logic for character counting also takes into effect the current number of characters required for t.co URL wrapping.
(From the "Code Example" section.)
Given that, I wrote the following code to build a tweet and balance the URL length and article length:
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter]) {
SLComposeViewController *twitterViewController = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
[twitterViewController addURL:[NSURL URLWithString:self.article.url]];
NSString *titleToShare = self.article.title;
while ([twitterViewController setInitialText:[NSString stringWithFormat:#"%# (via #SyllableApp)", titleToShare]]) {
titleToShare = [titleToShare substringToIndex:titleToShare.length - 1];
}
[self presentViewController:twitterViewController animated:YES completion:nil];
}
Which basically adds the URL then constructs the rest of the tweet by looping through the setInitialText: method until it returns YES, decreasing the length of the title by 1 each time it returns NO in order to get closer to the required length.
But it never returns YES! Even when I know it should. I was using one article where it could potentially exceed 140 characters as the title is 105 characters long and the URL is 55, plus the app credit. So it should theoretically be able to shorten the title down and then add it fine, but it never happens.
So what's going on? How do I accomplish link attachment with SLComposeViewController?
while ([twitterViewController setInitialText:[NSString stringWithFormat:#"%# (via #SyllableApp)", titleToShare]])
=>
while (![twitterViewController setInitialText:[NSString stringWithFormat:#"%# (via #SyllableApp)", titleToShare]])
There is a ! missing in condition, so you shorten the post when it fits, not when it is too long ;)
The problem with this approach is that it works only on iOS6.
SLComposeViewController *social = [[SLComposeViewController alloc] init];
NSString *stringToShare = #"";
for (int i = 0; i < 150; i++)
{
stringToShare = [stringToShare stringByAppendingString:#"x"];
}
NSLog(#"%#",[social setInitialText:stringToShare]?#"YES":#"NO");
yields different results on iOS6 (NO) and iOS7 (YES). The answer to this behaviour comes from the documentation of SLComposeViewController
// Sets the initial text to be posted. Returns NO if the sheet has already been
// presented to the user. On iOS 6.x, this returns NO if the specified text
// will not fit within the character space currently available; on iOS 7.0 and
// later, you may supply text with a length greater than the service supports,
// and the sheet will allow the user to edit it accordingly.
- (BOOL)setInitialText:(NSString *)text;
Probably is worth either having different approaches on iOS6 and 7, or check the length without using SLComposeViewController method.
As imihaly said, you did miss a "!".
And 140 characters count is the limit of title only, not including URL.So your title is 105 characters long which is less than 140,this method should return YES.
There is an open bug with link lengths not getting calculated correctly (radar://10469407). This might be related. You might try sending a Tweet with a link in it to check which URL shortener is being used (I imagine it's using t.co, but I could be wrong).