Verwenden von HTML und lokalen Bildern in UIWebView

164

Ich habe eine UIWebView in meiner App, mit der ich ein Bild anzeigen möchte, das mit einer anderen URL verknüpft ist.

Ich benutze

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

Das Problem ist, dass das Bild nicht geladen wird (dh nicht gefunden werden kann), obwohl es als Ressource in meinem Projekt hinzugefügt und in das Bundle kopiert wurde.

Ich habe versucht, mit NSBundle den vollständigen Pfad des Bildes abzurufen, und es wird immer noch nicht in der Webansicht angezeigt.

Irgendwelche Ideen?

Jasarien
quelle
Ab iPhone OS 3.0 kann ich das nicht mehr. :( Weitere Informationen (StackOverflow.com).
Joe D'Andrea
8
Warum die Abwahl? : /
Jasarien
5
Es ist nicht unbedingt so, dass sie böse sind. Vielleicht hatten sie einen legitimen Grund? Wir werden es wahrscheinlich nie erfahren. Wenn sie nur die Höflichkeit hätten zu erklären, warum sie in einem Kommentar
abgelehnt haben
63
Es sollte obligatorisch sein, einen Kommentar zu einer Abstimmung abzugeben.
Robert
@ Jasarien: Ich brauche die gleiche Funktionalität. Ich kann jedoch nicht verstehen, was in htmlString in [webView loadHTMLString: htmlString baseURL: baseURL] übergeben werden soll und wie ich <img src = "image.jpg" /> mein Bild in html eingefügt habe.
iPhone

Antworten:

291

Verwenden relativer Pfade oder Dateien: Pfade zum Verweisen auf Bilder funktionieren mit UIWebView nicht. Stattdessen müssen Sie den HTML-Code mit der richtigen baseURL in die Ansicht laden:

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

Sie können dann wie folgt auf Ihre Bilder verweisen:

<img src="myimage.png">

(von uiwebview überarbeitet )

Adam Alexander
quelle
15
[[NSBundle mainBundle] bundleURL] Wir können dies als bundleURL verwenden
Naveen Shan
2
Für mich bedeutet dies lediglich, dass ich in meiner Webansicht eine Zeichenfolge habe, die ich für meinen htmlString definiert habe. dh alles, was auf der Seite angezeigt wird, ist "tour.html"
Chewie The Chorkie
Als Nebenbemerkung, wenn Sie versuchen, Javascript-Dateien im Gegensatz zu Bildern zu laden, müssen Sie auch dies betrachten: stackoverflow.com/a/3629479/385619
Willster
im Fall von Xamarin ad MonoTouch webvie.LoadHtmlString (strig, NSBundle.MainBundle.BundleUrl);
Erik Simonic
1
Arbeiten Sie perfekt im Simulator, aber nicht in meinem Gerät
jose920405
46

Benutze das:

[webView loadHTMLString:htmlString baseURL:[[NSBundle mainBundle] bundleURL]];
Lithu TV
quelle
5
Aber Ihre Antwort ist identisch mit der Antwort, die vor 3 Jahren gepostet wurde ... Ihre Antwort bietet nichts anderes, sie musste nicht gepostet werden, da die akzeptierte Antwort bereits das abdeckte, was Sie gepostet haben.
Jasarien
13
Es ist eine praktische einzeilige Version der akzeptierten Antwort - kein Schaden, wenn Sie sie hier haben.
MusiGenesis
9
@Jasarien Diese Antwort von Adam Alexander war bis August 2009 die einzige Lösung. Ab Max OS X Version 10.6 wurde diese neue Eigenschaft bundleURLin NSBundle hinzugefügt. Sie müssen nicht bundlePath nehmen und in eine URL konvertieren. Für Benutzer, die in Versionen über 10.6 arbeiten, ist dies eine bessere Lösung.
Rineez
Ich habe in letzter Zeit viel Aktivität in diesem Beitrag gesehen. Und niemand hat bemerkt, warum es so ist?
Lithu TV
24

Ich bin auch gerade auf dieses Problem gestoßen. In meinem Fall handelte es sich um einige Bilder, die nicht lokalisiert waren, und andere, die - in mehreren Sprachen - waren. Eine Basis-URL hat die Bilder für mich nicht in lokalisierten Ordnern abgerufen. Ich habe dies folgendermaßen gelöst:

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

Verwenden Sie dann imgHTMLTag in Ihrem UIWebView-HTML-Code, wenn Sie den Inhalt laden.

Ich hoffe, das hilft jedem, der auf das gleiche Problem gestoßen ist.

Anton
quelle
1
Verwenden file://war das, was ich brauchte.
Also
Schön, genau das, was ich brauchte
Rubberduck
8

Versuchen Sie, eine Base64-Bildzeichenfolge zu verwenden.

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

NSString *strEncoded = [data base64Encoding];   

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

Ich hatte ein ähnliches Problem, aber alle Vorschläge halfen nicht.

Das Problem war jedoch die * .png selbst. Es hatte keinen Alphakanal . Irgendwie ignoriert Xcode während des Bereitstellungsprozesses alle PNG-Dateien ohne Alpha-Kanal .


quelle
Was hast du getan, um daraus herauszukommen? Haben Sie eine Lösung gefunden? Ich stehe vor dem gleichen Problem. UIWebView zeigt keine Bilder an, da es keinen Alpha-Kanal hat.
Spaleja
1
Ich habe Gimp verwendet, um meinen PNG-Dateien einen Alpha-Kanal hinzuzufügen. Siehe docs.gimp.org/en/gimp-layer-alpha-add.html
3

Sie können Ihrem Projekt einen Ordner hinzufügen (z. B. WEB mit Unterordnern css, img und js sowie die Datei test.html), indem Sie Dateien zu "MyProj hinzufügen" und Ordnerreferenzen erstellen auswählen . Der folgende Code kümmert sich nun um alle verwiesenen Bilder, CSS und Javascript

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

In Swift 3:

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

Dies funktionierte für mich auch dann, wenn sich das Bild ohne Änderungen in einem Ordner befand.

MrAn3
quelle
2

Nachdem ich einige Kapitel im iOS 6-Programmier-Cookbok gelesen und angefangen habe, Objective-C- und iOS-Programmierung zu lernen, möchte ich nur hinzufügen, dass, wenn man Ressourcen aus einem benutzerdefinierten Bundle laden und diese in einer Webansicht verwenden möchte kann es so erreicht werden:

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

Anschließend können Sie in Ihrem HTML-Code auf eine Ressource verweisen, indem Sie das "benutzerdefinierte" Bundle als Basispfad verwenden:

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

Schnelle Version der Antwort von Lithu TV:

webView.loadHTMLString(htmlString, baseURL: NSBundle.mainBundle().bundleURL)
Musa almatri
quelle
1

Schnelle Version von Adam Alexanders Ziel C Antwort:

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

Wenn Sie relative Links zu Bildern verwenden, werden die Bilder nicht angezeigt, da nach dem Kompilieren der iOS-App nicht alle Ordnerstrukturen erhalten bleiben. Was können Sie tun , ist Ihre lokale Web konvertieren Ordner in ein Bündel anstatt durch Hinzufügen der ‚ .bundle ‘ Dateinamenerweiterung.

Wenn Ihre lokale Website in einem Ordner " www " enthalten ist, sollte dieser in " www.bundle " umbenannt werden. Dadurch können die Bildordner und die Verzeichnisstruktur beibehalten werden. Laden Sie dann die Datei ' index.html ' als HTML-Zeichenfolge mit ' baseURL ' (festgelegt auf www.bundle path) in das WebView , um das Laden relativer Bildlinks zu ermöglichen.

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];
}
David Douglas
quelle
0

Diese Antworten haben mir geholfen - insbesondere die Datei: \\ xxxxxxx.xxx, aber ich musste eine Problemumgehung durchführen, um das Bild anzuzeigen.

In meinem Fall habe ich eine HTML-Datei auf meinem Server, die ich in das Dokumentenverzeichnis herunterlade. Ich möchte, dass es mit einer lokalen Grafik in einer UIWebView angezeigt wird, die ich nicht zum Arbeiten bringen konnte. Folgendes habe ich getan:

  1. Kopieren Sie die Datei aus dem NSBundle in das lokale Dokumentenverzeichnis
  2. Verweisen Sie auf die Datei in meinem HTML-Dokument als "Datei: \\ Dateiname.png".

Kopieren Sie die Datei beim Start in das Dokumentenverzeichnis:

-(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);
}
DoctorG
quelle
-7

Meine komplexe Lösung (oder Tutorial) für RSS-Feed (in RSSItems erhalten) funktioniert nur auf dem Gerät:

#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]);
                               }
                           }];

und

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

}}

on View Controller

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

#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

Teil eines HTML mit Bild

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

Bild gespeichert für Name htc-one-tab-7-concept-1 (1) .jpg

WINSergey
quelle