使用 UIWebView 搜索以突出显示 PDF 中的文本

2023-12-07

我是 ios 开发的新手,我有 UIWebView 用于显示来自 URL 的 Pdf 页面文章。我需要搜索字符串或文本并突出显示。我无法使用 UIWebView 搜索并突出显示 PDF 中的文本。Pdf 加载正常,但搜索文本未突出显示。它仅适用于我在 PDF 中需要的 html

Mycode

视图控制器.h

#import <UIKit/UIKit.h>
#import "SearchWebView.h"
@interface ViewController : UIViewController<UIWebViewDelegate>
{
IBOutlet SearchWebView *webView1;
}
@end

视图控制器.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *targetURL = [NSURL URLWithString:@"http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/pdf_open_parameters.pdf"];
NSURLRequest *request = [NSURLRequest requestWithURL:targetURL];
webView1.delegate=self;
[webView1 loadRequest:request];
[webView1 highlightAllOccurencesOfString:@"guide"];
}

-(void)webViewDidFinishLoad:(UIWebView *)webView
{
 [webView1 highlightAllOccurencesOfString:@"guide"];
}

@end

搜索WebView.h

#import <Foundation/Foundation.h>

@interface SearchWebView : UIWebView

- (NSInteger)highlightAllOccurencesOfString:(NSString*)str;
- (void)removeAllHighlights;

@end

搜索WebView.m

#import "SearchWebView.h"

@implementation SearchWebView

- (NSInteger)highlightAllOccurencesOfString:(NSString*)str
{
NSString *path = [[NSBundle mainBundle] pathForResource:@"SearchWebView" ofType:@"js"];
NSString *jsCode = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
[self stringByEvaluatingJavaScriptFromString:jsCode];

NSString *startSearch = [NSString stringWithFormat:@"MyApp_HighlightAllOccurencesOfString('%@')",str];
[self stringByEvaluatingJavaScriptFromString:startSearch];

NSString *result = [self stringByEvaluatingJavaScriptFromString:@"MyApp_SearchResultCount"];
return [result integerValue];
}

- (void)removeAllHighlights
{
[self stringByEvaluatingJavaScriptFromString:@"MyApp_RemoveAllHighlights()"];
}

@end

搜索WebView.js

 // We're using a global variable to store the number of occurrences
  var MyApp_SearchResultCount = 0;

 // helper function, recursively searches in elements and their child nodes
function MyApp_HighlightAllOccurencesOfStringForElement(element,keyword) {
if (element) {
    if (element.nodeType == 3) {        // Text node
        while (true) {
            var value = element.nodeValue;  // Search for keyword in text node
            var idx = value.toLowerCase().indexOf(keyword);

            if (idx < 0) break;             // not found, abort

            var span = document.createElement("span");
            var text = document.createTextNode(value.substr(idx,keyword.length));
            span.appendChild(text);
            span.setAttribute("class","MyAppHighlight");
            span.style.backgroundColor="yellow";
            span.style.color="black";
            text = document.createTextNode(value.substr(idx+keyword.length));
            element.deleteData(idx, value.length - idx);
            var next = element.nextSibling;
            element.parentNode.insertBefore(span, next);
            element.parentNode.insertBefore(text, next);
            element = text;
            MyApp_SearchResultCount++;  // update the counter
        }
    } else if (element.nodeType == 1) { // Element node
        if (element.style.display != "none" && element.nodeName.toLowerCase() != 'select') {
            for (var i=element.childNodes.length-1; i>=0; i--) {
                MyApp_HighlightAllOccurencesOfStringForElement(element.childNodes[i],keyword);
            }
        }
    }
}
}

// the main entry point to start the search
function MyApp_HighlightAllOccurencesOfString(keyword) {
MyApp_RemoveAllHighlights();
MyApp_HighlightAllOccurencesOfStringForElement(document.body, keyword.toLowerCase());
}

// helper function, recursively removes the highlights in elements and their childs
function MyApp_RemoveAllHighlightsForElement(element) {
if (element) {
    if (element.nodeType == 1) {
        if (element.getAttribute("class") == "MyAppHighlight") {
            var text = element.removeChild(element.firstChild);
            element.parentNode.insertBefore(text,element);
            element.parentNode.removeChild(element);
            return true;
        } else {
            var normalize = false;
            for (var i=element.childNodes.length-1; i>=0; i--) {
                if (MyApp_RemoveAllHighlightsForElement(element.childNodes[i])) {
                    normalize = true;
                }
            }
            if (normalize) {
                element.normalize();
            }
        }
    }
}
return false;
}

 // the main entry point to remove the highlights
function MyApp_RemoveAllHighlights() {
MyApp_SearchResultCount = 0;
MyApp_RemoveAllHighlightsForElement(document.body);
}

就我而言,我通过在搜索栏和我的搜索栏中输入的文本从网页视图中加载的页面中搜索文本搜索WebView.js

var uiWebview_SearchResultCount = 0;

/*!
 @method     uiWebview_HighlightAllOccurencesOfStringForElement
 @abstract   // helper function, recursively searches in elements and their child nodes
 @discussion // helper function, recursively searches in elements and their child nodes

 element    - HTML elements
 keyword    - string to search
 */

function uiWebview_HighlightAllOccurencesOfStringForElement(element,keyword) {

    if (element) {
        if (element.nodeType == 3) {        // Text node
            while (true) {
                //if (counter < 1) {
                var value = element.nodeValue;  // Search for keyword in text node
                var idx = value.toLowerCase().indexOf(keyword);

                if (idx < 0) break;             // not found, abort

                //(value.split);

                //we create a SPAN element for every parts of matched keywords
                var span = document.createElement("span");
                var text = document.createTextNode(value.substr(idx,keyword.length));
                span.appendChild(text);

                span.setAttribute("class","uiWebviewHighlight");
                span.style.backgroundColor="purple";
                span.style.color="white";

                uiWebview_SearchResultCount++;    // update the counter

                text = document.createTextNode(value.substr(idx+keyword.length));
                element.deleteData(idx, value.length - idx);
                var next = element.nextSibling;
                element.parentNode.insertBefore(span, next);
                element.parentNode.insertBefore(text, next);
                element = text;
            }
        } else if (element.nodeType == 1) { // Element node
            if (element.style.display != "none" && element.nodeName.toLowerCase() != 'select') {
                for (var i=element.childNodes.length-1; i>=0; i--) {
                    uiWebview_HighlightAllOccurencesOfStringForElement(element.childNodes[i],keyword);
                }
            }
        }
    }
}

// the main entry point to start the search
function uiWebview_HighlightAllOccurencesOfString(keyword) {
    uiWebview_RemoveAllHighlights();
    uiWebview_HighlightAllOccurencesOfStringForElement(document.body, keyword.toLowerCase());
}

// helper function, recursively removes the highlights in elements and their childs
function uiWebview_RemoveAllHighlightsForElement(element) {
    if (element) {
        if (element.nodeType == 1) {
            if (element.getAttribute("class") == "uiWebviewHighlight") {
                var text = element.removeChild(element.firstChild);
                element.parentNode.insertBefore(text,element);
                element.parentNode.removeChild(element);
                return true;
            } else {
                var normalize = false;
                for (var i=element.childNodes.length-1; i>=0; i--) {
                    if (uiWebview_RemoveAllHighlightsForElement(element.childNodes[i])) {
                        normalize = true;
                    }
                }
                if (normalize) {
                    element.normalize();
                }
            }
        }
    }
    return false;
}

// the main entry point to remove the highlights
function uiWebview_RemoveAllHighlights() {
    uiWebview_SearchResultCount = 0;
    uiWebview_RemoveAllHighlightsForElement(document.body);
}

在我的 .m 中,我搜索在搜索栏中输入的任何文本,例如:

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
    [self removeAllHighlights];
    int resultCount = [self highlightAllOccurencesOfString:searchBar.text];
    if (resultCount <= 0)
    {
       alert = [[UIAlertView alloc] initWithTitle:@"No Match Found!"
                                                        message:[NSString stringWithFormat:@"No results found for this: %@", searchBar.text]
                                                       delegate:nil
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles:nil];
        [alert show];

    }
    [searchBar resignFirstResponder];
}

我的highlightAllOccurencesOfString 方法的工作原理如下:

- (NSInteger)highlightAllOccurencesOfString:(NSString*)str
{

    NSString *filePath  = [[NSBundle mainBundle] pathForResource:@"UIWebViewSearch" ofType:@"js" inDirectory:@""];
    NSData *fileData    = [NSData dataWithContentsOfFile:filePath];
    NSString *jsString  = [[NSMutableString alloc] initWithData:fileData encoding:NSUTF8StringEncoding];
    [webView stringByEvaluatingJavaScriptFromString:jsString];
    NSString *startSearch   = [NSString stringWithFormat:@"uiWebview_HighlightAllOccurencesOfString('%@')",str];
    [webView stringByEvaluatingJavaScriptFromString:startSearch];
    NSString *result        = [webView stringByEvaluatingJavaScriptFromString:@"uiWebview_SearchResultCount"];
    return [result integerValue];
}

我的removeAllHighlights方法是:

- (void)removeAllHighlights
{
    [webView stringByEvaluatingJavaScriptFromString:@"uiWebview_RemoveAllHighlights()"];
}

现在将所有这些与您的情况进行比较。希望对您有帮助。如果有任何疑问,请随时问我。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 UIWebView 搜索以突出显示 PDF 中的文本 的相关文章

  • OpenGL-ES、iPhone 和间歇性错误:GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES (0x8CD6)

    我有一个在 UIView 中使用 OpenGL ES 和 EAGLContext 的应用程序 非常类似于 Apple 的 GLPaint 示例代码应用程序 我在 iPhone 4 上看到这个错误 但在 iPad 上却没有 这可能很重要 大多
  • 使用 JSONKit 解析 JSON 文件

    我正在构建一个音叉应用程序 货叉应允许最多 12 个预设节距 此外 我希望允许用户选择一个主题 每个主题都会加载一组预设 不必使用所有预设 我的配置文件看起来像这样 theme A3 comment An octave below conc
  • 在 Swift 中的 For 循环中更改对象的属性

    我创建了一个名为 ShoppingList 的简单结构 struct ShoppingList var shoppingListId NSNumber var title String var groceryItems GroceryIte
  • 无法在 xcode 8 beta 6 上编译 AWS CustomIdentityProvider

    我在 iOS 应用程序中使用 Amazon Cognito 和 Facebook 登录 直到 beta 5 为止此代码从这个SO线程 https stackoverflow com questions 37597388 aws cognit
  • 自定义 UINavigationController UINavigationBar

    基本上我想要一个定制UINavigationBar 我不希望它是 半透明 或任何东西 就像图片应用程序一样 我基本上想完全删除它 但我仍然希望能够在按下导航控制器时添加后退按钮等 并且我想要视图 例如 UITableViewControll
  • 检测 iPhone 屏幕是否打开/关闭

    有没有办法检测 iPhone 的屏幕是打开还是关闭 例如 当按下手机的屏幕锁定按钮时 我一直在使用 void applicationWillResignActive UIApplication application 为此类事件做准备 在大
  • iOS - 在相机上放置自定义叠加层(垂直对齐)。顶部黑条的大小

    我正在寻找以下问题的编程解决方案 我想在相机 iOS 上绘制自定义叠加层 我希望它位于相机输出视图的垂直中央 我已经完成了相对于屏幕而不是相机图片居中绘制自定义视图 为此 我需要获得顶部黑条的大小 我怎么才能得到它 顶部和底部栏的大小不相等
  • iOS绘图3D图形库[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在搜索一个可以帮助我绘制 3D 图表的库 我想要类似的东西这一页 http www math uri edu bkaskosz fla
  • UITableViewCell 内嵌套 UIStackView 内的 UILabel 有时会被截断

    我的一个表设置中有一个表视图单元格 其中包含以下视图层次结构 外部水平 stackview 固定到单元格内容视图的尾部 前部 底部和顶部边缘 右侧标签固定到其父 stackViewHackView 的尾部 前部 底部和顶部边缘 在我的控制器
  • 使用 Dirac 在 iPhone 中进行实时音高变化 [重复]

    这个问题在这里已经有答案了 可能的重复 iPhone 上的实时音调变换 https stackoverflow com questions 1100495 real time pitch shifting on the iphone 我已经
  • 如何将设备上未保存的图片上传到dropbox帐户?(IOS)

    Dropbox RestClient 仅保存文件 所以我想先将图像保存在本地文件夹中 然后上传它 结果它保存了文件 但它已损坏 NSString localPath NSBundle mainBundle pathForResource I
  • AdMob 和 DFP 广告联盟之间的区别?

    我正在尝试在我的 iOS 应用程序上显示横幅广告和插页式广告 但现在我对广告网络感到困惑 AdMob 与 DFP 有何不同 哪一种更适合投放广告 有人可以提供帮助吗 提前致谢 AdMob 是一个广告网络 作为发布商 您可以通过展示从网络投放
  • 使用ios sdk在youtube上上传视频的方法[重复]

    这个问题在这里已经有答案了 可能的重复 如何从 iOS 应用程序中将视频上传到 YouTube https stackoverflow com questions 3528568 how do i upload a video to you
  • iOS:如何创建核心数据库的备份副本?以及如何导出/导入该副本?

    我想为我的应用程序的用户提供创建核心数据数据库备份的可能性 特别是在他切换到新设备等情况下 我该怎么做呢 特别是如何重新导入该文件 我的意思是 假设他制作了数据库的备份副本 然后更改了大量内容并想要重置为以前保存的备份副本 我该怎么做呢 T
  • Objective-C 点表示法与类方法?

    请注意 我特别指的是点表示法与类方法一起使用 而不是与实例方法一起使用 出于好奇 我想看看如果我尝试在类方法中使用 Objective C 点表示法语法会发生什么 我的实验如下 import
  • Facebook 登录打开错误的应用程序

    我正在尝试使用 facebook 实现应用程序的登录 但每次我尝试登录时 它都建议打开错误的应用程序 我尝试了一些在这里找到的东西 但没有成功 在 Facebook 的开发者页面上我添加了一个后缀 我的 plist 如下 有谁知道发生了什么
  • 获取所有ios应用程序的全局列表[重复]

    这个问题在这里已经有答案了 我想对苹果应用商店进行一些全球统计 一个瓶颈是至少获取所有当前活动应用程序的 ID 这 9 位数字 有谁知道如何获取 iOS 应用商店中当前活动应用程序的所有 id 的完整列表 更好的是特定类别的所有 ID 例如
  • 如何制作像 Facebook 应用程序一样的登录屏幕?

    如何制作像 Facebook 应用程序一样带有 电子邮件 和 密码 文本字段的登录屏幕 Facebook登入 http extdesenv com wp content uploads 2012 05 facebook login ios
  • 如何安全地重命名 iOS 分发配置文件?

    我几个小时前刚刚提交了我的第一个应用程序 现在处于 等待审核 状态 但我犯了一个错误 我已经命名了我的分配配置文件My Company Distribution Profile 我应该做的事情被命名为我的发行版配置文件My GAME Dis
  • 从应用程序内发送电子邮件中的图像和文本

    如何从我的应用程序内通过电子邮件发送图像和文本 表格数据形式 请大家帮忙并提出建议 谢谢 void sendMailWithImage UIImage image if MFMailComposeViewController canSend

随机推荐

  • 没有为名称为“success”映射的类型“dynamic-jasper”定义结果类型

    我正在尝试将 DynamicJasper 5 0 0 与 Struts 2 3 4 一起使用 我正在使用以下代码以 PDF 格式显示数据 动作课中 try FastReportBuilder drb new FastReportBuilde
  • 如何检测 JavaScript 算术运算中的数字上溢/下溢?

    我今天正在进行编码测试 目标是在 JavaScript 中添加字符串的 2 个整数表示时捕获所有边缘情况 我无法得到的一种情况是如何检测 IEEE 754 数字中存储的总和的上溢 下溢 通常 在 C 中 我会查看数字的二进制表示形式 但在
  • Laravel 5.3 多个文件上传

    如何上传多个文件Laravel 5 3 如果我尝试使用 1 个图像 它可以工作 但不会上传多个图像 这是我的代码 if request gt hasFile attachment foreach request gt allFiles at
  • emberjs 中命名约定的混乱

    也许有些人只是知道答案 但我试图理解以下内容 假设您正在声明一个视图 App FooView Ember View extend 现在引用这个视图App Router结果出现以下错误 router get applicationContro
  • 在 VB.Net 或 C# 中保存设置

    即使关闭程序后如何保存我想要的设置 假设 如果我有一个Checkbox我运行该程序 如果我检查了它 即使我再次重新打开程序 我也想保持这种状态 我希望你明白我想要什么 我是新手 所以慢慢来 谢谢 我建议使用应用程序设置属性绑定 mrunio
  • ASP.NET 错误:无法加载文件或程序集 App_Web_z9w33txs

    您是如何摆脱这些烦人的 ASP NET 错误的 无法加载文件或程序集 App Web z9w33txs Version 0 0 0 0 Culture neutral PublicKeyToken null 这种事以前只发生在我身上一次 它
  • CUDA - 将设备数据复制到主机?

    我有设备变量 在这个变量中 我在设备中分配并填充一个数组 但在将数据获取到主机时遇到问题 cudaMemcpy return cudaErrorInvalidValue错误 我该怎么做 PS 代码只是示例 我知道 在这种特殊情况下我可以使用
  • MatterJS 预先计算最终位置

    我正在尝试创建一个简单的 2D 游戏 其中一个球掉落到地面 受到一些障碍物的影响 这些障碍物会改变球的最终位置 我使用 MatterJS 作为 2D 物理引擎 但它实际上是不可预测的 使用相同的参数我的球总是处于不同的最终位置 有没有办法预
  • 使用 RxJS 和 twitter-stream-api 模块订阅流

    好吧 我是 Rx 的初学者 不幸的是 我对 js 和 js 中的流也很陌生 我用这个https github com trygve lie twitter stream api连接到 Twitter 流 api 并接收带有推文的 json
  • 在 OpenCV 中求椭圆的成本

    我正在使用基于的代码这个例子并想知道是否有任何方法可以找出椭圆拟合的 好 程度 我有一些椭圆 它们只非常适合我的数据 我想去掉它们 而有些椭圆几乎是完美的 我想保留非常合身的款式 去掉不合身的款式 我怎样才能做到这一点opencv 您可以在
  • 无法将类型“System.Windows.Forms.Control”转换为“T”

    我正在尝试创建通用 FindControl 方法 但出现以下错误 无法将类型 System Windows Forms Control 转换为 T Code public T Control
  • Heroku 静态文件未加载,Django

    我正在努力推动我的 Django 项目到 Heroku 但它没有加载静态文件 I used this设置这些东西 一切都很好 但我无法解决静态文件的问题 我的目录结构是这样的 help the needy help the needy in
  • 为什么附加到小书签中的innerHTML 会覆盖整个页面?

    我有这个小书签 javascript document getElementsByTagName div 0 innerHTML Chuck Norris 现在很明显supposed采取第一个div在页面上 并将 Chuck Norris
  • 将 MKMapView 上的距离转换为 UIView 的距离

    如何将 MKMapView 上的距离 例如 400 米 转换为 UIView 的距离 我想显示取决于 MKMapView 上当前缩放级别的 MKAnnotationView 首先 创建一个长度为 400 米的区域 MKCoordinateR
  • 我无法在 Android 中从 GCM onMessage 打开对话框

    当使用谷歌云消息发送消息到我的android应用程序时 我不知道如何打开是或否对话框 如javasrcript确认框 如果他们点击 是 则在浏览器中打开一个网站 如果点击 是 则不执行任何操作不 我花了太多时间 不愿意向您展示这个基本代码
  • 动态路线的routes.rb中的Rails访问请求

    我们的网站应该允许显示与给定 url 相关的不同内容 类似于 wordpress 中的多站点 我们只有一个安装并根据 url 提供内容 因为有必要使用正确的语言来路由 所以我想使用 动态路由 方法来提供正确的内容 我现在的问题是 如果路由是
  • 在netbeans中使用Ant在构建过程中动态获取外部库的最新版本

    我真的是一个蚂蚁新手 这是我的问题 我在 netbeans 中有一个项目 它使用当前位于 lib 目录中的几个外部库 我希望我的 netbeans 在尝试构建项目时动态获取这些库的最新版本 这是可行的还是我走在完全错误的道路上 我有每个外部
  • AWS Lambda 使用 firebase-admin 初始化应用程序超时

    我使用 Lambda 到 Firebase 消息 我参考this 但 lambda 函数仍然超时 因为它无法连接到谷歌服务器 处理程序 js START imports const firebase require firebase adm
  • 通过 HTTPS 读取使用 HTTP 设置的 cookie

    使用HTTP设置的cookie可以使用HTTPS读取吗 仅当通过安全方式 HTTPS 连接时 浏览器才会发送使用 Secure 关键字设置的 Cookie 除此之外没有区别 如果不存在 secure 则 cookie 可能会通过不安全的连接
  • 使用 UIWebView 搜索以突出显示 PDF 中的文本

    我是 ios 开发的新手 我有 UIWebView 用于显示来自 URL 的 Pdf 页面文章 我需要搜索字符串或文本并突出显示 我无法使用 UIWebView 搜索并突出显示 PDF 中的文本 Pdf 加载正常 但搜索文本未突出显示 它仅