การใช้ HTML และ Local Images ภายใน UIWebView


164

ฉันมี UIWebView ในแอพของฉันซึ่งฉันต้องการใช้เพื่อแสดงภาพที่จะเชื่อมโยงไปยัง URL อื่น

ฉันกำลังใช้

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

ปัญหาคือรูปภาพไม่โหลด (เช่นไม่พบ) แม้ว่าจะเพิ่มเป็นทรัพยากรในโครงการของฉันและคัดลอกลงในชุดข้อมูล

ฉันได้ลองใช้ NSBundle เพื่อให้ได้เส้นทางที่เต็มของรูปภาพและใช้สิ่งนั้นและมันยังไม่ปรากฏในมุมมองเว็บ

ความคิดใด ๆ


ฉันไม่สามารถทำเช่นนี้กับ iPhone OS 3.0 ได้อีกต่อไป :( ข้อมูลเพิ่มเติม (StackOverflow.com).
Joe D'Andrea

8
ทำไมถึงลงคะแนน? : /
Jasarien

5
ไม่จำเป็นว่าพวกเขาจะชั่วร้าย พวกเขาอาจมีเหตุผลที่ถูกกฎหมาย? เราคงไม่มีทางรู้ ถ้าเพียง แต่พวกเขาต้องการมีมารยาทที่จะอธิบายว่าทำไมพวกเขาลงคะแนนในความคิดเห็น ...
Jasarien

63
มันควรจะบังคับให้เขียนความคิดเห็นลงคะแนน
Robert

@ Jasarien: ฉันต้องการฟังก์ชั่นเดียวกัน แต่ฉันไม่เข้าใจว่าควรส่งสิ่งใดใน htmlString ใน [webView loadHTMLString: htmlString baseURL: baseURL] และฉันใส่ <img src = "image.jpg" /> ภาพของฉันเป็น html ได้อย่างไร
iPhone

คำตอบ:


291

การใช้พา ธ หรือไฟล์ที่เกี่ยวข้อง: พา ธ เพื่ออ้างถึงรูปภาพไม่สามารถใช้งานได้กับ UIWebView แต่คุณต้องโหลด HTML ในมุมมองด้วย baseURL ที่ถูกต้อง:

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

จากนั้นคุณสามารถอ้างถึงภาพของคุณเช่นนี้:

<img src="myimage.png">

(จากuiwebview มาเยือนอีกครั้ง )


15
[[NSBundle mainBundle] bundleURL] เราสามารถใช้สิ่งนี้เป็น bundleURL
Naveen Shan

2
ทั้งหมดนี้ทำให้ฉันเป็นสตริงใน webview ของฉันที่ฉันกำหนดไว้สำหรับ htmlString ของฉัน นั่นคือทั้งหมดที่แสดงบนหน้าคือ "tour.html"
Chewie The Chorkie

ในฐานะที่เป็น sidenote หากคุณพยายามโหลดไฟล์จาวาสคริปต์เมื่อเทียบกับภาพคุณจะต้องมองดูสิ่งนี้เช่นกัน: stackoverflow.com/a/3629479/385619
Willster

ในกรณีของ Xamarin กับ MonoTouch webvie.LoadHtmlString (strig, NSBundle.MainBundle.BundleUrl);
Erik Simonic

1
ทำงานได้สมบูรณ์แบบในเครื่องจำลอง แต่ไม่ใช่ในอุปกรณ์ของฉัน
jose920405

46

ใช้สิ่งนี้:

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

5
แต่คำตอบของคุณเหมือนกับคำตอบที่โพสต์เมื่อ 3 ปีที่แล้ว ... คำตอบของคุณไม่มีอะไรที่แตกต่างออกไปมันไม่จำเป็นต้องโพสต์เพราะคำตอบที่ยอมรับนั้นครอบคลุมสิ่งที่คุณโพสต์ไว้แล้ว
Jasarien

13
เป็นคำตอบที่ยอมรับได้แบบบรรทัดเดียวและสะดวกสบาย - ไม่มีอันตรายใด ๆ เกิดขึ้นที่นี่
MusiGenesis

9
@Jasarien คำตอบของ Adam Alexander เป็นทางออกเดียวจนถึงเดือนสิงหาคม 2009 แต่จาก Max OS X เวอร์ชัน 10.6 คุณสมบัติใหม่นี้bundleURLได้ถูกเพิ่มเข้าไปใน NSBundle ไม่จำเป็นต้องใช้ bundlePath และแปลงเป็น URL ดังนั้นสำหรับคนที่ทำงานในรุ่นที่สูงกว่า 10.6 นี่จึงเป็นทางออกที่ดีกว่า
rineez

ได้เห็นกิจกรรมมากมายในโพสต์นี้เมื่อเร็ว ๆ นี้และไม่มีใครสังเกตว่าทำไม
Lithu TV

24

ฉันเพิ่งพบปัญหานี้เช่นกัน ในกรณีของฉันฉันจัดการกับภาพบางภาพที่ไม่ได้แปลเป็นภาษาท้องถิ่นและอื่น ๆ ที่มี - ในหลายภาษา URL พื้นฐานไม่ได้รับรูปภาพภายในโฟลเดอร์ที่แปลเป็นภาษาท้องถิ่นสำหรับฉัน ฉันแก้ไขสิ่งนี้โดยทำสิ่งต่อไปนี้:

// 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];

จากนั้นใช้ imgHTMLTag ในรหัส UIWebView HTML ของคุณเมื่อคุณโหลดเนื้อหา

ฉันหวังว่านี่จะช่วยให้ทุกคนที่พบปัญหาเดียวกัน


1
การใช้file://คือสิ่งที่ฉันต้องการ
ดังนั้นเมื่อ

ดีสิ่งที่ฉันต้องการ
Rubberduck

8

ลองใช้สตริงอิมเมจ base64

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

NSString *strEncoded = [data base64Encoding];   

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

6

ฉันมีปัญหาอย่างง่าย ๆ แต่ข้อเสนอแนะทั้งหมดไม่ได้ช่วย

อย่างไรก็ตามปัญหาคือ * .png เอง มันไม่มีช่องอัลฟา อย่างใดXcode ละเว้นไฟล์ png ทั้งหมดโดยไม่มีช่องอัลฟาในระหว่างกระบวนการปรับใช้


คุณทำอะไรเพื่อออกไปจากสิ่งนี้? คุณพบวิธีการแก้ปัญหาใด ๆ ? ฉันกำลังเผชิญกับปัญหาเดียวกัน UIWebView ไม่แสดงภาพเนื่องจากไม่มี No Alpha Channel
spaleja

1
ฉันใช้ Gimp เพื่อเพิ่มช่องอัลฟาลงในไฟล์ png ของฉัน ดูdocs.gimp.org/en/gimp-layer-alpha-add.html

3

คุณสามารถเพิ่มโฟลเดอร์ (WEB พูดกับโฟลเดอร์ย่อย CSS, img และ js และไฟล์ test.html) กับโครงการของคุณโดยการเลือกเพิ่มไฟล์ "Myproj"และเลือกสร้างโฟลเดอร์อ้างอิง ตอนนี้โค้ดต่อไปนี้จะดูแลเกี่ยวกับรูปภาพที่อ้างถึง css และ javascript ทั้งหมด

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

3

ในสวิฟต์ 3:

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

สิ่งนี้ใช้ได้สำหรับฉันแม้ว่าภาพจะอยู่ในโฟลเดอร์โดยไม่มีการดัดแปลงใด ๆ


2

หลังจากได้อ่านบทสองบทในการเขียนโปรแกรม iOS 6 Cookbok และเริ่มเรียนรู้เกี่ยวกับการเขียนโปรแกรมวัตถุประสงค์และ c iOS ฉันต้องการเพิ่มว่าถ้าใครจะโหลดทรัพยากรจากชุดข้อมูลที่กำหนดเองและใช้ในมุมมองเว็บ มันสามารถทำได้เช่นนี้

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

จากนั้นใน html ของคุณคุณสามารถอ้างถึงทรัพยากรโดยใช้ชุด "กำหนดเอง" เป็นเส้นทางหลักของคุณ:

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


1

Adam Alexanders Objective C รุ่น Swift คำตอบ:

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

0

หากคุณใช้ลิงก์ที่เชื่อมโยงไปยังรูปภาพรูปภาพจะไม่แสดงเนื่องจากโครงสร้างโฟลเดอร์ทั้งหมดจะไม่ถูกเก็บรักษาไว้หลังจากที่รวบรวมแอพ iOS สิ่งที่คุณสามารถทำได้คือแปลงเว็บโฟลเดอร์ในเครื่องเป็นบันเดิลแทนโดยเพิ่มนามสกุลไฟล์ ' .bundle '

ดังนั้นหากเว็บไซต์ท้องถิ่นของคุณมีอยู่ในโฟลเดอร์ " www " ควรเปลี่ยนชื่อเป็น " www.bundle " สิ่งนี้อนุญาตให้โฟลเดอร์รูปภาพและโครงสร้างไดเร็กทอรีถูกสงวนไว้ จากนั้นโหลดไฟล์ ' index.html ' ลงใน WebView เป็นสตริง HTML ที่มี ' baseURL ' (ตั้งค่าเป็นเส้นทาง www.bundle) เพื่อเปิดใช้งานการโหลดลิงก์รูปภาพที่เกี่ยวข้อง

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

คำตอบเหล่านี้ช่วยฉันได้โดยเฉพาะไฟล์: \\ xxxxxxx.xxx แต่ฉันต้องทำวิธีแก้ปัญหาเพื่อแสดงภาพ

ในกรณีของฉันฉันมีไฟล์ HTML บนเซิร์ฟเวอร์ซึ่งฉันดาวน์โหลดไปยังไดเรกทอรีเอกสาร ฉันต้องการที่จะแสดงด้วยกราฟิกท้องถิ่นใน UIWebView ซึ่งฉันไม่สามารถทำงานได้ นี่คือสิ่งที่ฉันทำ:

  1. คัดลอกไฟล์จาก NSBundle ไปยังไดเรกทอรีเอกสารท้องถิ่น
  2. อ้างอิงไฟล์ในเอกสาร HTML ของฉันเป็น "file: \\ filename.png"

ดังนั้นในการเริ่มต้นคัดลอกไฟล์ไปยังไดเรกทอรีเอกสาร:

-(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

โซลูชันที่ซับซ้อนของฉัน (หรือบทช่วยสอน) สำหรับ rss-feed (รับใน RSSItems) ใช้งานได้บนอุปกรณ์เท่านั้น:

#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
}

}

บนตัวควบคุมมุมมอง

- (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];

}

รายการระดับ 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

ส่วนหนึ่งของ html ใด ๆ ที่มีภาพ

<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>

บันทึกภาพสำหรับชื่อhtc-one-tab-7-concept-1 (1) .jpg

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.