Getting the selected text of a UIWebView - ios

I'm trying to access the currently selected text in a UIWebView using the following line of code:
NSString *highlighted = [_webView stringByEvaluatingJavaScriptFromString:#"window.getSelection();"];
But it only returns an emtpy string. Any ideas about what I'm missing?

Try with this :
NSString * highlighted = [_webView stringByEvaluatingJavaScriptFromString:#"window.getSelection().toString()"];

I think this will help
NSString *selection = [self.webView stringByEvaluatingJavaScriptFromString:#"window.getSelection().toString()"];
Please check this link too

I have also stumbled upon this problem, and this is really frustrating. I don't exactly remember from where I got the solution, but it's the following; getSelection() returns a JavaScript object that cannot be converted to a string. You have to explicitly convert it to a string from the JavaScrtipt code:
NSString *highlighted = [_webView stringByEvaluatingJavaScriptFromString:#"window.getSelection().toString();"];
See it in action.

In swift: self.webView.stringByEvaluatingJavaScriptFromString("window.getSelection().toString();")
The semicolon at the end of the Javascript is required, without this it did not work!

Try this with swift:
// stringByEvaluatingJavaScript retunr optional string, hence use if-let block
if let selectedString = self.webView.stringByEvaluatingJavaScript(from: "window.getSelection().toString()") {
print(selectedString - \(selectedString))
}

Related

Is there a way not to type the "http(s)://" prefix in UIWebview for user to go to a website?

I have the following lines of code used to let user type in the URL address of a website and present the website within the app:
- (IBAction)buttonPressed:(id)sender {
[self.myView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.myText.text]]];
[self.myText resignFirstResponder];
}
But it turns out to be that you have to type http:// every time you type in the URL address, otherwise it will not work, is there a way for me not to do that? thanks
You could add it if it's not there:
NSString* fullyQualifiedURL = [#"http://" stringByAppendingString:self.myText.text];

Hiding A Button Based on Exact URL

I'm trying to hide a button only when a certain URL is being displayed in a UIWebView. This is the code I'm using to do so:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request {
NSString *host = [request.URL host];
if ([host isEqualToString:#"http://example.com/cheese"]) {
_backButton.hidden = YES;
} else {
_backButton.hidden = NO;
}
return 0;
}
When I test it to see if the back button is hidden, it never is. It stays in plain view whether "example.com/cheese" is loaded or not. (That /cheese part is pretty important as well, maybe it is only checking the host and not the full URL?)
Either way, I have no idea what to change or add to get this working. Any help is greatly appreciated!
Update: I added in an NSLog just before the if statement, and it's not even firing. I also changed the code to the answer below (thanks again rmaddy). I have no idea why this method is not firing.
The host part of the URL is just that, the host. If the URL is:
http://example.com/cheese
then the host is just example.com.
If you want to compare the full URL then do this:
NSString *full = [request.URL absoluteString];
if ([full isEqualToString:#"http://example.com/cheese"]) {
}
If you want to compare just the host then do this:
NSString *host = [request.URL host];
if ([host isEqualToString:#"example.com"]) {
}
What's odd is that you have it correct in the second bit of code you posted. It is wrong in the first bit of code you posted.
Also, in the first block of code, you call return 0 at the end. You should return either YES or NO since the return type is BOOL.

Comparing NSString to UITextField text never gets called

I record the value of the text in my UITextField and I want to compare the text to the original text field value later. I try something like this, but I never get the NSLog to be displayed. Any ideas why?
defaultTopicText = topicTextField.text;
if ([topicTextField.text isEqualToString:defaultTopicText]){
NSLog(#"YES");
}else{
NSLog(topicTextField.text);
NSLog(defaultTopicText);
}
The code looks exactly like you see it. The first line I assign the value and the other - I compare with it. And it's not being called.
EDIT:
The code itself IS getting called and I also get the same values when I put them in NSLog. Might the problem be that the text field contains #"\n" characters?
NSLog gives me this:
2013-03-18 20:45:22.037 myapp[524:907]
Here comes the text
2013-03-18 20:45:22.039 myapp[524:907]
Here comes the text
Try to print out the value of the topicTextField.text and see what is shows. otherwise set the breakpoints to see if you are reaching to that particular line of code.
You coud also try comparing after removing the white spaces and new line, if there might be any
NSString *trimmmedText = [topicTextField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([trimmmedText isEqualToString:defaultTopicText]){
NSLog(#"YES");
}
Try changing to this:
NSString *newString = [defaultTopicText stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([newString isEqualToString:defaultTopicText]){
NSLog(#"YES");
}
I typed the following the figured out the answer...
running this should give you your answer:
if(!defaultTopicText){
NSLog(#"defaultTopicText is nil");
}else{
NSLog(#"defaultTopicText is a: %#".[defaultTopicText classname]);
}
defaultTopicText = topicTextField.text;
if ([topicTextField.text localizedCaseInsensitiveCompare:defaultTopicText] == NSOrderedSame){
NSLog(#"YES");
}else{
NSLog(#"\"%#\" != \"%#\"",defaultTopicText, topicTextField.text);
}
Then I realized: topicTextField.text can only not be the same object as itself using this comparison method if it is nil.
topicTextField.text has to be nil... so it ends up executing:
id var = nil;
[var isEqual:nil];
and the runtime makes that return 0;
... so fix your outlet to topicTextField

UItextfield initialized with empty string? not null? nor nil?

i have a uitextfield, when it is initialized and i didn't input any values into it, i found the value of the uitextfield is not null nor nil.
NSString *notes = (notesField.text)?(notesField.text):#"hello";
NSLog(#"notes: %#",notes);
it returns nothing for notes
NSString *notes1;
//or use legnth
if ([notesField.text isEqual:#""]) {
notes1=#"hello";
NSLog(#"empty textfield: %#",notes1);
//then it returns "hello"
}
else
{
notes1=notesField.text;
NSLog(#"not empty textfield: %#",notes1);
}
Why is that? Can I still user ternary operator ?
like this ?
NSString *notes = ([notesField.text length])?(notesField.text):#"hello";
You can use
NSString *notes = ([notesField.text length])?(notesField.text):#"hello";
OR
NSString *notes = ([notesField.text length]==0)?#"hello":(notesField.text);
OR
NSString *notes = ([notesField.text isEqualToString:#""])?#"hello":(notesField.text);
And for the case when your UITextField has no entry (initial case), use the second or third option , that will be beter. NSString *notes = ([notesField.text length])?#"hello":(notesField.text); won't work fine as you expect because notesField.text will be TRUE even if there is no text in textfield. So you should use notesField.text.length or [notesField.text isEqualToString:#""].
Hope its clear now.
The docs for UITextField state
text
The text displayed by the text field.
#property(nonatomic, copy) NSString *text
Discussion
This string is #"" by default.
Note: if compiling under Xcode 5.02 or 5.1 and running in iOS earlier than iOS7, UITextField.text is initialised to nil. If running in iOS7+ it is initialised to #"".
If compiling in Xcode 4.6.3 or earlier then UITextField.text has (always) been initialised to #"", as per the documentation.
Radar bug: 16336863
UITextField must be initializing itself with a non-nil empty string. In situations where you don't care if the string is empty or nil, you can simply check the length property:
if (!notesField.text.length) {
// text is nil or empty
}
Or using the ternary operator:
NSString *s = notesField.text.length ? notesField.text : #"Default";
This works because sending the -length selector to a nil object will return a default value of 0.
That approach will work just fine.
As for why it's an empty string instead of nil, it's generally bad practice to return nil for something unless you want to indicate an error or an uninitialized state. An empty text field has a value. It's just an empty string.

Appending HTML to UIWebView

I'm trying to append some HTML to a UIWebView. It doesn't work and instead overwrites the existing HTML, since oldHTML below is always empty. The HTML string starts off as
<html><font color="0x0000FF">Blue text</font></html>
Code:
NSString *oldHTML = [myWebView stringByEvaluatingJavaScriptFromString:#"document.documentElement.innerHTML"];
NSString *html = [NSString stringWithFormat:#"%#%#%#%#", #"<html>", oldHTML, htmlToAdd, #"</html>"];
[myWebView loadHTMLString:html baseURL:nil];
So my questions are:
Is it even possible to get the html from a UIWebView?
If so, why does the first line fail/what is the correct method?
Is there a better way to append HTML to a UIWebView?
Thanks for any help.
I suspect at the point you're trying to get the old html, your page hasn't completed loading yet, which is why it's returning a blank string.
Try creating and assigning a UIWebViewDelegate for your view that implements webViewDidFinishLoad: and putting your code above in that function - oldHTML should be non-blank at that point.
As for a better way, you can inject the content via javascript with something like this:
NSString *injectSrc = #"var i = document.createElement('div'); i.innerHTML = '%#';document.documentElement.appendChild(i);";
NSString *runToInject = [NSString stringWithFormat:injectSrc, #"Hello World"];
[myWebView stringByEvaluatingJavascriptFromString:runToInject];
I'd recommend cleaning this up a bit, as it's not totally secure, but it should get the idea across of using javascript to inject new elements onto the page.

Resources