Sử dụng HTML và hình ảnh cục bộ trong UIWebView


164

Tôi có UIWebView trong ứng dụng của mình mà tôi muốn sử dụng để hiển thị hình ảnh sẽ liên kết với một url khác.

Tôi đang sử dụng

<img src="image.jpg" /> to load the image.

Vấn đề là hình ảnh không tải (nghĩa là không thể tìm thấy) mặc dù nó được thêm dưới dạng tài nguyên trong dự án của tôi và được sao chép vào gói.

Tôi đã thử sử dụng NSBundle để có được đường dẫn đầy đủ của hình ảnh và sử dụng nó và nó vẫn không hiển thị trong chế độ xem web.

Có ý kiến ​​gì không?


Tôi không còn có thể làm điều này kể từ iPhone OS 3.0. :( Thêm thông tin (StackOverflow.com).
Joe D'Andrea

8
Tại sao bỏ phiếu xuống? : /
Jasarien 17/03/2016

5
Không nhất thiết là họ xấu xa. Có lẽ họ đã có một lý do chính đáng? Có lẽ chúng ta sẽ không bao giờ biết. Giá như họ có phép lịch sự để giải thích lý do tại sao họ bỏ phiếu trong một bình luận ...
Jasarien 17/03

63
Nó là bắt buộc để viết bình luận về một cuộc bỏ phiếu xuống.
Robert

@Jasarien: Tôi cần chức năng tương tự. nhưng tôi không thể hiểu những gì nên được truyền trong htmlString trong [webView loadHTMLString: htmlString baseURL: baseURL] và cách tôi đặt <img src = "image.jpg" /> hình ảnh của tôi trong html.
iPhone

Câu trả lời:


291

Sử dụng đường dẫn hoặc tệp tương đối: đường dẫn để tham chiếu đến hình ảnh không hoạt động với UIWebView. Thay vào đó, bạn phải tải HTML vào dạng xem với cơ sở chính xác:

NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
[webView loadHTMLString:htmlString baseURL:baseURL];

Sau đó, bạn có thể tham khảo hình ảnh của bạn như thế này:

<img src="myimage.png">

(từ uiwebview xem lại )


15
[[NSBundle mainBundle] bundleURL] chúng ta có thể sử dụng nó như bundleURL
Naveen Shan

2
Tất cả điều này đối với tôi là cho tôi một chuỗi trong webview mà tôi đã xác định cho htmlString của mình. tức là tất cả những gì nó hiển thị trên trang là "tour.html"
Chewie The Chorkie

Là một sidenote, nếu bạn đang cố tải các tệp javascript trái ngược với hình ảnh, bạn cũng cần phải xem xét điều này: stackoverflow.com/a/3629479/385619
Willster

trong trường hợp Xamarin quảng cáo MonoTouch webvie.LoadHtmlString (strig, NSBundle.MainBundle.BundleUrl);
Erik Simonic

1
Hoạt động hoàn hảo trong trình giả lập, nhưng không phải trong thiết bị của tôi
jose920405

46

Dùng cái này:

[webView loadHTMLString:htmlString baseURL:[[NSBundle mainBundle] bundleURL]];

5
Nhưng câu trả lời của bạn giống hệt với câu trả lời được đăng 3 năm trước ... Câu trả lời của bạn không có gì khác biệt, nó không cần phải đăng vì câu trả lời được chấp nhận đã bao gồm những gì bạn đã đăng.
Jasarien

13
Đây là phiên bản một dòng thuận tiện của câu trả lời được chấp nhận - không có hại gì khi có nó ở đây.
MusiGenesis

9
@Jasarien câu trả lời của Adam Alexander là giải pháp duy nhất cho đến tháng 8 năm 2009. Nhưng từ Max OS X phiên bản 10.6, tài sản mới này bundleURLđã được thêm vào NSBundle. Không cần phải lấy bundlePath và chuyển đổi sang URL. Vì vậy, đối với những người làm việc trong các phiên bản cao hơn 10.6, điều này mang lại một giải pháp tốt hơn.
rineez

nhìn thấy rất nhiều hoạt động -ve trong bài đăng này gần đây..Và không ai lưu ý tại sao nó lại như vậy?
Litva TV

24

Tôi chỉ gặp vấn đề này quá. Trong trường hợp của tôi, tôi đã xử lý một số hình ảnh không được bản địa hóa và những hình ảnh khác - bằng nhiều ngôn ngữ. Một URL cơ sở không nhận được hình ảnh trong các thư mục được bản địa hóa cho tôi. Tôi đã giải quyết điều này bằng cách làm như sau:

// make sure you have the image name and extension (for demo purposes, I'm using "myImage" and "png" for the file "myImage.png", which may or may not be localized)
NSString *imageFileName = @"myImage";
NSString *imageFileExtension = @"png";

// load the path of the image in the main bundle (this gets the full local path to the image you need, including if it is localized and if you have a @2x version)
NSString *imagePath = [[NSBundle mainBundle] pathForResource:imageFileName ofType:imageFileExtension];

// generate the html tag for the image (don't forget to use file:// for local paths)
NSString *imgHTMLTag = [NSString stringWithFormat:@"<img src=\"file://%@\" />", imagePath];

Sau đó, sử dụng imgHTMLTag trong mã UIWebView HTML của bạn khi bạn tải nội dung.

Tôi hy vọng điều này sẽ giúp bất cứ ai gặp phải vấn đề tương tự.


1
Sử dụng file://là những gì tôi cần.
Vậy là hết

Thật tuyệt, chính xác là những gì tôi cần
Rubberduck 28/07/17

8

hãy thử sử dụng chuỗi hình ảnh base64.

NSData* data = UIImageJPEGRepresentation(image, 1.0f);

NSString *strEncoded = [data base64Encoding];   

<img src='data:image/png;base64,%@ '/>,strEncoded

6

Tôi đã có một vấn đề tương tự, nhưng tất cả các đề xuất đều không giúp được gì.

Tuy nhiên, vấn đề là chính * .png. Nó không có kênh alpha . Bằng cách nào đó Xcode bỏ qua tất cả các tệp png mà không có kênh alpha trong quá trình triển khai.


Bạn đã làm gì để thoát khỏi điều này? Bạn đã tìm thấy bất kỳ giải pháp? Tôi đang phải đối mặt với vấn đề tương tự. UIWebView không hiển thị hình ảnh vì nó không có Kênh Alpha.
spaleja

1
Tôi đã sử dụng Gimp để thêm kênh alpha vào các tệp png của mình. Xem docs.gimp.org/en/gimp-layer-alpha-add.html

3

Bạn có thể thêm thư mục (giả sử WEB với các thư mục con css, img và js và tệp test.html) vào dự án của bạn bằng cách chọn Thêm tệp vào "MyProj" và chọn Tạo tham chiếu thư mục . Bây giờ đoạn mã sau sẽ quan tâm đến tất cả các hình ảnh được giới thiệu, css và javascript

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"WEB/test.html" ofType:nil];
[webView  loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:filePath]]];

3

Trong Swift 3:

webView.loadHTMLString("<img src=\"myImg.jpg\">", baseURL: Bundle.main.bundleURL)

Điều này làm việc cho tôi ngay cả khi hình ảnh nằm trong một thư mục mà không có bất kỳ sửa đổi nào.


2

Sau khi đọc một vài chương trong Cookbok Lập trình iOS 6 và bắt đầu học lập trình Object-c và iOS, tôi chỉ muốn nói thêm rằng, nếu ai đó sẽ tải tài nguyên từ gói tùy chỉnh và sử dụng nó trong chế độ xem web , nó có thể được thực hiện như thế này:

NSString *resourcesBundlePath = [[NSBundle mainBundle] pathForResource:@"Resources" ofType:@"bundle"];
NSBundle *resourcesBundle = [NSBundle bundleWithPath:resourcesBundlePath];
[self.outletWebView loadHTMLString:[html description] baseURL:[resourcesBundle bundleURL]];

Sau đó, trong html của bạn, bạn có thể tham chiếu đến một tài nguyên bằng cách sử dụng gói "tùy chỉnh" làm đường dẫn cơ sở của mình:

body {
    background-image:url('img/myBg.png');
}

1

Phiên bản Swift của câu trả lời của Litva TV:

webView.loadHTMLString(htmlString, baseURL: NSBundle.mainBundle().bundleURL)

1

Phiên bản Swift của Adam Alexanders Objective C trả lời:

let logoImageURL = NSURL(fileURLWithPath: "\(Bundle.main.bundlePath)/PDF_HeaderImage.png")

0

Nếu bạn sử dụng các liên kết tương đối đến hình ảnh thì hình ảnh sẽ không hiển thị vì tất cả các cấu trúc thư mục không được bảo tồn sau khi ứng dụng iOS được biên dịch. Những gì bạn có thể làm là chuyển đổi thư mục web cục bộ của bạn thành một gói thay vì thêm phần mở rộng tên tệp ' .bundle '.

Vì vậy, nếu trang web địa phương của bạn được chứa trong một thư mục " www ", thì trang này sẽ được đổi tên thành " www.bundle ". Điều này cho phép các thư mục hình ảnh và cấu trúc thư mục được bảo tồn. Sau đó tải tệp ' index.html ' vào WebView dưới dạng chuỗi HTML với ' baseURL ' (được đặt thành đường dẫn www.bundle) để cho phép tải các liên kết hình ảnh tương đối.

NSString *mainBundlePath = [[NSBundle mainBundle] resourcePath];
NSString *wwwBundlePath = [mainBundlePath stringByAppendingPathComponent:@"www.bundle"];
NSBundle *wwwBundle = [NSBundle bundleWithPath:wwwBundlePath];
if (wwwBundle != nil) {
    NSURL *baseURL = [NSURL fileURLWithPath:[wwwBundle bundlePath]];
    NSError *error = nil;
    NSString *page = [[NSBundle mainBundle] pathForResource:@"index.html" ofType:nil];
    NSString *pageSource = [NSString stringWithContentsOfFile:page encoding:NSUTF8StringEncoding error:&error];
    [self.webView loadHTMLString:pageSource baseURL:baseURL];
}

0

Những câu trả lời này đã giúp tôi - cụ thể là tệp: \\ xxxxxxx.xxx, nhưng tôi phải làm một cách giải quyết để hiển thị hình ảnh.

Trong trường hợp của tôi, tôi có một tệp HTML trên máy chủ của mình mà tôi tải xuống thư mục tài liệu. Tôi muốn nó hiển thị với một đồ họa cục bộ trong UIWebView mà tôi không thể làm việc. Đây là những gì tôi đã làm:

  1. Sao chép tệp từ NSBundle vào thư mục tài liệu cục bộ
  2. Tham chiếu tệp trong tài liệu HTML của tôi dưới dạng "tệp: \\ filename.png"

Vì vậy, khi khởi động, sao chép tập tin vào thư mục tài liệu:

-(BOOL)copyBundleFilesToDocumentsDirectoryForFileName:(NSString *)fileNameToCopy OverwriteExisting:(BOOL)overwrite {
        //GET DOCUMENTS DIR
        //Search for standard documents using NSSearchPathForDirectoriesInDomains
        //First Param = Searching the documents directory
        //Second Param = Searching the Users directory and not the System
        //Expand any tildes and identify home directories.
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDir = [paths objectAtIndex:0];

        //COPY FILE FROM NSBUNDLE File to Local Documents Dir
        NSString *writableFilePath = [documentsDir  stringByAppendingPathComponent:fileNameToCopy];

        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSError *fileError;

        DDLogVerbose(@"File Copy From Bundle to Documents Dir would go to this path: %@", writableFilePath);

        if ([fileManager fileExistsAtPath:writableFilePath]) {
            DDLogVerbose(@"File %@ already exists in Documents Dir", fileNameToCopy);

            if (overwrite) {
                [fileManager removeItemAtPath:writableFilePath error:nil];
                DDLogVerbose(@"OLD File %@ was Deleted from  Documents Dir Successfully", fileNameToCopy);
            } else {
                return (NO);
            }
        }

        NSArray *fileNameParts = [fileNameToCopy componentsSeparatedByString:@"."];
        NSString *bundlePath = [[NSBundle mainBundle]pathForResource:[fileNameParts objectAtIndex:0] ofType:[fileNameParts objectAtIndex:1]];
        BOOL success = [fileManager copyItemAtPath:bundlePath toPath:writableFilePath error:&fileError];

        if (success) {
            DDLogVerbose(@"Copied %@ from Bundle to Documents Dir Successfully", fileNameToCopy);
        } else {
            DDLogError(@"File %@ could NOT be copied from bundle to Documents Dir due to error %@!!", fileNameToCopy, fileError);
        }

    return (success);
}

-7

Giải pháp phức tạp của tôi (hoặc hướng dẫn) cho rss-feed (nhận trong RSSItems) chỉ hoạt động trên thiết bị:

#define CACHE_DIR       [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]

for (RSSItem *item in _dataSource) {

    url = [NSURL URLWithString:[item link]];
    request = [NSMutableURLRequest requestWithURL:url];
    [request setHTTPMethod:@"GET"];

    [NSURLConnection sendAsynchronousRequest:request
                                       queue:queue
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

                               @autoreleasepool {

                                   if (!error) {

                                       NSString *html = [[NSString alloc] initWithData:data
                                                                              encoding:NSWindowsCP1251StringEncoding];

                                       {
                                           NSError *error = nil;

                                           HTMLParser *parser = [[HTMLParser alloc] initWithString:html error:&error];

                                           if (error) {
                                               NSLog(@"Error: %@", error);
                                               return;
                                           }

                                           HTMLNode *bodyNode = [parser body];

                                           NSArray *spanNodes = [bodyNode findChildTags:@"div"];

                                           for (HTMLNode *spanNode in spanNodes) {
                                               if ([[spanNode getAttributeNamed:@"class"] isEqualToString:@"page"]) {

                                                   NSString *absStr = [[response URL] absoluteString];
                                                   for (RSSItem *anItem in _dataSource)
                                                       if ([absStr isEqualToString:[anItem link]]){

                                                           NSArray *spanNodes = [bodyNode findChildTags:@"img"];
                                                           for (HTMLNode *spanNode in spanNodes){
                                                               NSString *imgUrl = [spanNode getAttributeNamed:@"src"];
                                                               if (imgUrl){
                                                                   [anItem setImage:imgUrl];
                                                                   break;
                                                               }
                                                           }

                                                           [anItem setHtml:[spanNode rawContents]];
                                                           [self subProcessRSSItem:anItem];
                                                       }
                                               }
                                           }

                                           [parser release];
                                       }

                                       if (error) {
                                           NSLog(@"Error: %@", error);
                                           return;
                                       }

                                       [[NSNotificationCenter defaultCenter] postNotificationName:notification_updateDatasource
                                                                                           object:self
                                                                                         userInfo:nil];

                                   }else
                                       NSLog(@"Error",[error userInfo]);
                               }
                           }];

- (void)subProcessRSSItem:(RSSItem*)item{

NSString *html = [item html];
if (html) {

    html = [html stringByReplacingOccurrencesOfString:@"<div class=\"clear\"></div>"
                                           withString:@""];

    html = [html stringByReplacingOccurrencesOfString:@"<p class=\"link\">"
                                           withString:@""];

    html = [html stringByReplacingOccurrencesOfString:@"<div class=\"page\">"
                                           withString:@""];

    html = [html stringByReplacingOccurrencesOfString:@"</div>"
                                           withString:@""];

    NSArray *array1 = [html componentsSeparatedByString:@"<a"];
    if ([array1 count]==2) {
        NSArray *array2 = [html componentsSeparatedByString:@"a>"];

        html = [[array1 objectAtIndex:0] stringByAppendingString:[array2 objectAtIndex:1]];
    }

    NSURL *url;
    NSString *fileName;
    NSString *filePath;
    BOOL success;
    if ([item image]) {

        url = [NSURL URLWithString:
                      [hostString stringByAppendingString:[item image]]];
        NSData *imageData = [NSData dataWithContentsOfURL:url];

        fileName = [[[url relativePath] componentsSeparatedByString:@"/"] lastObject];

        filePath = [NSString stringWithFormat:@"%@/%@",
                              CACHE_DIR,
                              fileName];

        //save image locally
        success = [[NSFileManager defaultManager] createFileAtPath:filePath
                                                               contents:imageData
                                                             attributes:nil];

        //replace links
        html = [html stringByReplacingOccurrencesOfString:[item image]
                                               withString:filePath];

        [item setImage:fileName];

        //Передадим обновление интерфейса, снабдив индексом обновляемой ячейки
        [[NSNotificationCenter defaultCenter] postNotificationName:notification_updateRow
                                                            object:self
                                                          userInfo:[NSDictionary dictionaryWithObject:@([_dataSource indexOfObject:item])
                                                                                               forKey:@"row"]];
    }

    //finalize html
    html = [NSString stringWithFormat:@"<html><body>%@</body></html>",html];

    fileName = [[[item link] componentsSeparatedByString:@"/"] lastObject];
    filePath = [NSString stringWithFormat:@"%@/%@",
                CACHE_DIR,
                fileName];
    success = [[NSFileManager defaultManager] createFileAtPath:filePath
                                                      contents:[html dataUsingEncoding:NSUTF8StringEncoding]
                                                    attributes:nil];

    [item setHtml:
     (success)?filePath:nil];//for direct download in other case
}

}

trên Xem bộ điều khiển

- (void)viewDidAppear:(BOOL)animated{

RSSItem *item = [[DataSingleton sharedSingleton] selectedRSSItem];

NSString* htmlString = [NSString stringWithContentsOfFile:[item html]
                                                 encoding:NSUTF8StringEncoding error:nil];
NSURL *baseURL = [NSURL URLWithString:CACHE_DIR];

[_webView loadHTMLString:htmlString
                 baseURL:baseURL];

}

lớp rss

#import <Foundation/Foundation.h>

@interface RSSItem : NSObject

@property(nonatomic,retain) NSString *title;
@property(nonatomic,retain) NSString *link;
@property(nonatomic,retain) NSString *guid;
@property(nonatomic,retain) NSString *category;
@property(nonatomic,retain) NSString *description;
@property(nonatomic,retain) NSString *pubDate;
@property(nonatomic,retain) NSString *html;
@property(nonatomic,retain) NSString *image;
@end

một phần của bất kỳ html nào có hình ảnh

<html><body>
<h2>blah-blahTC One Tab 7</h2>
<p>blah-blah НТС One.</p>
<p><img width="600" height="412" alt="" src="/Users/wins/Library/Application Support/iPhone Simulator/5.0/Applications/2EAD8889-6482-48D4-80A7-9CCFD567123B/Library/Caches/htc-one-tab-7-concept-1(1).jpg"><br><br>
blah-blah (Hasan Kaymak) blah-blah HTC One Tab 7, blah-blah HTC One. <br><br>
blah-blah
 microSD.<br><br>
blah-blah Wi-Fi to 4G LTE.</p>
</p>
</body></html>

hình ảnh được lưu cho tên htc-one-tab-7-concept-1 (1) .jpg

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.