我正在开发我的第一个应用程序,它涉及从网站上的大量文本中搜索特定的文本字符串。我希望能够搜索特定字符串并突出显示所有实例,并且随着用户键入更多内容,它会自动更新突出显示的事件。类似于任何浏览器中的查找功能。
我在这里找到了这个问题,他们引用使用 UIWebViewSearch.js 来实现这一点,但我不确定如何将该文件添加到我的项目中,或者如何使用它。
到目前为止,我已经在我的应用程序中添加了一个搜索栏,但还没有对它做任何事情。想用这个功能和搜索栏一起搜索文本。
这是我的 ViewController 代码:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var webView: UIWebView!
@IBOutlet weak var searchBar: UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Place custom HTML onto the screen
let myURL = Bundle.main.url(forResource: "myHTML", withExtension: "html")
let requestObj = URLRequest(url: myURL!)
webView.loadRequest(requestObj)
// Code that provides a string containing
// JS code, ready to add to a webview.
if let path = Bundle.main.path(forResource: "UIWebViewSearch", ofType: "js"),
let jsString = try? String(contentsOfFile: path, encoding: .utf8) {
print(jsString)
} // end if
func searchBarSearchButtonClicked() {
let startSearch = "uiWebview_HighlightAllOccurencesOfString('\(str)')"
self.newsWebView .stringByEvaluatingJavaScript(from: startSearch)
}
} // end of viewDidLoad
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
} // end of didReceiveMemoryWarning
} // end of class ViewController
正如@jon-saw 所说:欢迎使用 StackOverflow :)
我只会回答你如何将 JavaScript 文件添加到你的项目中......这应该能让事情开始:)
您可以通过多种方式将文件添加到 Xcode,但这里是一种。
命名您的文件UIWebViewSearch.js
,然后单击“创建”
您现在UIWebViewSearch.js
在项目中调用了一个空文件,您可以在其中粘贴内容。
现在您的项目中有该文件,所以现在您只需要引用它。为此,您可以使用Bundle
which 可以为您加载项目中的资源。
If you look at the answer you referred to, you can see these lines of ObjC code in - (NSInteger)highlightAllOccurencesOfString:(NSString*)str
NSString *path = [[NSBundle mainBundle] pathForResource:@"UIWebViewSearch" ofType:@"js"];
NSString *jsCode = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
Translated to Swift that would look like this:
if let path = Bundle.main.path(forResource: "UIWebViewSearch", ofType: "js"),
let jsString = try? String(contentsOfFile: path, encoding: .utf8) {
print(jsString)
}
And that should give you a String
containing all your JS code, ready to add to a WebView for instance.
Hope that gives you something to start with.
OK, so you say:
I added my ViewController code to better communicate where I'm at. Kind of confused on how to implement the second part of his code you're referring to. Also not sure how to call the search from the searchBar. Is there a method I need to call within 'searchBarSearchButtonClicked()' method? Just found that method on the apple developer documentation, don't know if it's the correct one, though.
Lets break it down into pieces, I'll start with your ViewController
, as there are some problems in your viewDidLoad
:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Place custom HTML onto the screen
let myURL = Bundle.main.url(forResource: "myHTML", withExtension: "html")
let requestObj = URLRequest(url: myURL!)
webView.loadRequest(requestObj)
// Code that provides a string containing
// JS code, ready to add to a webview.
if let path = Bundle.main.path(forResource: "UIWebViewSearch", ofType: "js"),
let jsString = try? String(contentsOfFile: path, encoding: .utf8) {
print(jsString)
} // end if
func searchBarSearchButtonClicked() {
let startSearch = "uiWebview_HighlightAllOccurencesOfString('\(str)')"
self.newsWebView .stringByEvaluatingJavaScript(from: startSearch)
}
}
You've added your searchBarSearchButtonClicked
inside viewDidLoad
, but it should be declared as a function by itself (we'll get back to it later).
Furthermore, as I wrote in the comments below:
...One part that is run when the view is loaded and which loads the JavaScript from the bundle.
So lets fix your viewDidLoad
:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Place custom HTML onto the screen
let myURL = Bundle.main.url(forResource: "myHTML", withExtension: "html")
let requestObj = URLRequest(url: myURL!)
webView.loadRequest(requestObj)
// Code that provides a string containing
// JS code, ready to add to a webview.
if let path = Bundle.main.path(forResource: "UIWebViewSearch", ofType: "js"),
let jsString = try? String(contentsOfFile: path, encoding: .utf8) {
print(jsString)
//Use your jsString on the web view here.
newsWebView.stringByEvaluatingJavaScript(from: jsString)
}
}
As you can see, the searchBarSearchButtonClicked
function has been removed and we now use out jsString
on the newsWebView
.
OK, next part:
Also not sure how to call the search from the searchBar. Is there a method I need to call within 'searchBarSearchButtonClicked()' method? Just found that method on the apple developer documentation, don't know if it's the correct one, though.
You have your searchBarSearchButtonClicked()
method which you have found in the Apple Developer documentation, I'm guessing you're meaning this one
As you can see in the documentation (top bar), this function is from the UISearchBarDelete
class.
Delegation is a design pattern used in many of Apples frameworks. It allows you to write some generic components and let "someone else" (the delegate) decide what to do with the information from the component (bad explanation I know).
Think of your UISearchBar
for instance. If you were to implement a component that other developers could use as a search bar, how would you handle when the user searches for something? I'm thinking, how should your "customers" (the developers using your components) handle this? One way of doing this could be that the developers should subclass UISearchBar
and override a "user did search method". You could also use NSNotifications
and have the developer register for these notifications. Both of these methods are not pretty or clever.
Enter...the delegate.
UISearchBar
has a UISearchBarDelegate
and UISearchBarDelegate
is just a protocol as you can see. Now the UISearchBar
can ask its delegate for certain things, or inform the delegate about important events. So for instance, when the user taps the "Search" button UISearchBar
can call delegate.searchBarSearchButtonClicked(self)
which means "hey delegate, the user has clicked the search button on me...just thought you should know". And the delegate can then respond as it sees fit.
This means that any class can conform to UISearchBarDelegate
and handle the various tasks as it suits in their current situation.
OK, long story, hope you get the gist of it and I think you should read a bit more on delegation as it is a pattern used all over in Apples frameworks :)
So, in your case, you have a UISearchBar
, you should give that a delegate like so:
searchBar.delegate = self
And you need to tell the compiler that you intend to implement the UISearchBarDelegate
protocol. The Swift convention is to do this in an extension
after your ViewController
, just to keep things separated:
extension ViewController: UISearchBarDelegate {
}
And then you must also implement the methods of UISearchBarDelegate
that you are interested in listening to (note that some protocols have required methods, meaning that you MUST implement them but I don't think UISearchBar
has (otherwise you'll find out when the app crashes the first time you run it :)).
So in your case, you mentioned searchBarSearchButtonPressed
. As you can see it needs a UISearchBar
as a parameter. So your function ends out looking like this:
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
guard let currentSearchText = searchBar.text else {
return
}
let startSearch = "uiWebview_HighlightAllOccurencesOfString('\(currentSearchText)')"
newsWebView.stringByEvaluatingJavaScript(from: startSearch)
}
所以...您从搜索栏中获取当前文本,将其作为参数添加到您的startSearch
字符串中,然后将该startSearch
字符串传递给您的newsWebView
.
整个扩展看起来像这样。
.... last part of your ViewController class
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
} // end of didReceiveMemoryWarning
} // end of class ViewController
extension ViewController: UISearchBarDelegate {
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
guard let currentSearchText = searchBar.text else {
return
}
let startSearch = "uiWebview_HighlightAllOccurencesOfString('\(currentSearchText)')"
newsWebView.stringByEvaluatingJavaScript(from: startSearch)
}
}
你的viewDidLoad
结果看起来像这样(你必须将自己添加为 searchBar 的委托)
override func viewDidLoad() {
super.viewDidLoad()
searchBar.delegate = self //delegate set up
// Do any additional setup after loading the view, typically from a nib.
// Place custom HTML onto the screen
let myURL = Bundle.main.url(forResource: "myHTML", withExtension: "html")
let requestObj = URLRequest(url: myURL!)
webView.loadRequest(requestObj)
// Code that provides a string containing
// JS code, ready to add to a webview.
if let path = Bundle.main.path(forResource: "UIWebViewSearch", ofType: "js"),
let jsString = try? String(contentsOfFile: path, encoding: .utf8) {
print(jsString)
//Use your jsString on the web view here.
newsWebView.stringByEvaluatingJavaScript(from: jsString)
}
}
哇……写了很多……希望对你有帮助。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句