85

I have a .svg image file I want to display in my project.

I tried using UIImageView, which works for the .png & .jpg image formats, but not for the .svg extension. Is there any way to display a .svg image using UIWebView or UIImageView ?

Priyanka Kanse
  • 1,051
  • 1
  • 15
  • 27

16 Answers16

24

There is no Inbuilt support for SVG in Swift. So we need to use other libraries.

The simple SVG libraries in swift are :

1) SwiftSVG Library

It gives you more option to Import as UIView, CAShapeLayer, Path, etc

To modify your SVG Color and Import as UIImage you can use my extension codes for the library mentioned in below link,

Click here to know on using SwiftSVG library :
Using SwiftSVG to set SVG for Image

|OR|

2) SVGKit Library

2.1) Use pod to install :

pod 'SVGKit', :git => 'https://github.com/SVGKit/SVGKit.git', :branch => '2.x'

2.2) Add framework

Goto AppSettings
-> General Tab
-> Scroll down to Linked Frameworks and Libraries
-> Click on plus icon
-> Select SVG.framework

2.3) Add in Objective-C to Swift bridge file bridging-header.h :

#import <SVGKit/SVGKit.h>
#import <SVGKit/SVGKImage.h>

2.4) Create SvgImg Folder (for better organization) in Project and add SVG files inside it.

Note : Adding Inside Assets Folder won't work and SVGKit searches for file only in Project folders

2.5) Use in your Swift Code as below :

import SVGKit

and

let namSvgImgVar: SVGKImage = SVGKImage(named: "NamSvgImj")

Note : SVGKit Automatically apends extention ".svg" to the string you specify

let namSvgImgVyuVar = SVGKImageView(SVGKImage: namSvgImgVar)

let namImjVar: UIImage = namSvgImgVar.UIImage

There are many more options for you to init SVGKImage and SVGKImageView

There are also other classes u can explore

    SVGRect
    SVGCurve
    SVGPoint
    SVGAngle
    SVGColor
    SVGLength

    and etc ...
Sujay U N
  • 4,974
  • 11
  • 52
  • 88
  • Good explanation. But you should/can not use `SVGKImageView` directly. Instead `SVGKFastImageView`or `SVGKLayeredImageView` must be used. – d4Rk Jan 19 '18 at 09:21
  • Add `SVGKit.framework` in Linked Frameworks and Libraries – Naresh Nov 11 '20 at 14:03
21

SVG file support is added to Xcode 12.

enter image description here

Priya Talreja
  • 560
  • 6
  • 10
19

My solution to show .svg in UIImageView from URL. You need to install SVGKit pod

Then just use it like this:

import SVGKit

 let svg = URL(string: "https://openclipart.org/download/181651/manhammock.svg")!
 let data = try? Data(contentsOf: svg)
 let receivedimage: SVGKImage = SVGKImage(data: data)
 imageview.image = receivedimage.uiImage

or you can use extension for async download

extension UIImageView {
func downloadedsvg(from url: URL, contentMode mode: UIView.ContentMode = .scaleAspectFit) {
    contentMode = mode
    URLSession.shared.dataTask(with: url) { data, response, error in
        guard
            let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200,
            let mimeType = response?.mimeType, mimeType.hasPrefix("image"),
            let data = data, error == nil,
            let receivedicon: SVGKImage = SVGKImage(data: data),
            let image = receivedicon.uiImage
            else { return }
        DispatchQueue.main.async() {
            self.image = image
        }
    }.resume()
}
}

How to use:

let svg = URL(string: "https://openclipart.org/download/181651/manhammock.svg")!

imageview.downloadedsvg(from: svg)
Naresh
  • 16,698
  • 6
  • 112
  • 113
Vlad Bruno
  • 327
  • 3
  • 7
18

Try this code

var path: String = NSBundle.mainBundle().pathForResource("nameOfFile", ofType: "svg")!

        var url: NSURL = NSURL.fileURLWithPath(path)  //Creating a URL which points towards our path

       //Creating a page request which will load our URL (Which points to our path)
        var request: NSURLRequest = NSURLRequest(URL: url)
       webView.loadRequest(request)  //Telling our webView to load our above request
Komal Kamble
  • 424
  • 1
  • 8
  • 25
17

You can use SVGKit for example.

1) Integrate it according to instructions. Drag&dropping the .framework file is fast and easy.

2) Make sure you have an Objective-C to Swift bridge file bridging-header.h with import code in it:

#import <SVGKit/SVGKit.h>
#import <SVGKit/SVGKImage.h>

3) Use the framework like this, assuming that dataFromInternet is NSData, previously downloaded from network:

let anSVGImage: SVGKImage = SVGKImage(data: dataFromInternet)
myIUImageView.image = anSVGImage.UIImage

The framework also allows to init an SVGKImage from other different sources, for example it can download image for you when you provide it with URL. But in my case it was crashing in case of unreachable url, so it turned out to be better to manage networking by myself. More info on it here.

Vitalii
  • 4,267
  • 1
  • 40
  • 45
17

You can add New Symbol Image Set in .xcassets, then you can add SVG file in it

and use it same like image.

enter image description here

Note: This doesn't work on all SVG. You can have a look at the apple documentation

nikhilgohil11
  • 1,185
  • 15
  • 26
  • This will only work with a very specific subset of SVG files, cf. https://developer.apple.com/documentation/uikit/uiimage/creating_custom_symbol_images_for_your_app – Mick F Jan 28 '20 at 15:42
  • Thanks @DirtyHenry I have added in a note in answer. – nikhilgohil11 Jan 29 '20 at 06:08
12

Swift 3.0 version :

let path = Bundle.main.path(forResource: "svgNameFileHere", ofType: "svg")!
if path != "" {
    let fileURL:URL = URL(fileURLWithPath: path)
    let req = URLRequest(url: fileURL)
    self.webView.scalesPageToFit = false
    self.webView.loadRequest(req)
}
else {
   //handle here if path not found
}

Third party libraries

https://github.com/exyte/Macaw

https://github.com/mchoe/SwiftSVG

UIWebView and WKWebView booster to load faster

https://github.com/bernikovich/WebViewWarmUper

Community
  • 1
  • 1
Paresh Navadiya
  • 38,095
  • 11
  • 81
  • 132
9

In case you want to use a WKWebView to load a .svg image that is coming from a URLRequest, you can simply achieve it like this:

Swift 4

if let request = URLRequest(url: urlString), let svgString = try? String(contentsOf: request) {
  wkWebView.loadHTMLString(svgString, baseURL: request)
}

It's much simpler than the other ways of doing it, and you can also persist your .svg string somewhere to load it later, even offline if you need to.

GabrielaBezerra
  • 920
  • 11
  • 16
6

You can keep your images as strings and use WKWebView to display them:

let webView: WKWebView = {
    let mySVGImage = "<svg height=\"190\"><polygon points=\"100,10 40,180 190,60 10,60 160,180\" style=\"fill:lime;stroke:purple;stroke-width:5;fill-rule:evenodd;\"></svg>"
    let preferences = WKPreferences()
    preferences.javaScriptEnabled = false
    let configuration = WKWebViewConfiguration()
    configuration.preferences = preferences
    let wv = WKWebView(frame: .zero, configuration: configuration)
    wv.scrollView.isScrollEnabled = false
    wv.loadHTMLString(mySVGImage, baseURL: nil)
    return wv
}()
nanvel
  • 1,384
  • 1
  • 13
  • 16
5

SVGKit helped me on getting the image from URL.

First, add pod 'SVGKit' in your Podfile.

Second, import SVGKit into your class.

Third, create an object of SVGImage.

let mySVGImage: SVGKImage = SVGKImage(contentsOf: URL(string: path))

Finally, add this image to your UIImageView.

yourImageView.image = mySVGImage.uiImage
Ali Qaderi
  • 471
  • 7
  • 16
5

Since XCode 12, it is possible to add SVG assets to your project.

To add svg file to your project:

  1. Drag and drop your svg file into the assets catalog.
  2. Selected the newly added asset.
  3. Your svg image will be added as 1x. Select it and change the Scales property to Single Scale in attributes inspector.

enter image description here

Drunken Daddy
  • 7,326
  • 14
  • 70
  • 104
4

Here's a simple class that can display SVG images in a UIView

import UIKit

public class SVGImageView: UIView {
    private let webView = UIWebView()

    public init() {
        super.init(frame: .zero)
        webView.delegate = self
        webView.scrollView.isScrollEnabled = false
        webView.contentMode = .scaleAspectFit
        webView.backgroundColor = .clear
        addSubview(webView)
        webView.snp.makeConstraints { make in
            make.edges.equalTo(self)
        }
    }

    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    deinit {
        webView.stopLoading()
    }

    public func load(url: String) {
        webView.stopLoading()
        if let url = URL(string: fullUrl) {
            webView.loadRequest(URLRequest(url: url))
        }
    }
}

extension SVGImageView: UIWebViewDelegate {
    public func webViewDidFinishLoad(_ webView: UIWebView) {
        let scaleFactor = webView.bounds.size.width / webView.scrollView.contentSize.width
        if scaleFactor <= 0 {
            return
        }

        webView.scrollView.minimumZoomScale = scaleFactor
        webView.scrollView.maximumZoomScale = scaleFactor
        webView.scrollView.zoomScale = scaleFactor
    }
}
wes
  • 1,643
  • 2
  • 15
  • 12
  • did any one try this ? – cybergeeeek Feb 04 '19 at 07:27
  • 1
    @cybergeeeek I did an almost identical solution in Objective-C before, so this should work. The only downside is the slow loading time of the web view, so the images will appear a half a second after the screen is loaded. – turingtested Apr 27 '19 at 16:06
2

To render SVG file you can use Macaw. Also Macaw supports transformations, user events, animation and various effects.

You can render SVG file with zero lines of code. For more info please check this article: Render SVG file with Macaw.

DISCLAIMER: I am affiliated with this project.

Community
  • 1
  • 1
zapletnev
  • 493
  • 1
  • 5
  • 15
  • 8
    Can I ask you to please read [How to offer personal open-source libraries?](//meta.stackexchange.com/q/229085) This is clearly your own project, do disclose this in your posts. – Martijn Pieters Nov 25 '16 at 09:45
  • 1
    I gave Macaw just a try but quality of SVG ist too worse – coyer Nov 25 '16 at 12:32
2

As I know there are 2 different graphic formats:

  1. Raster graphics (uses bitmaps) and is used in JPEG, PNG, APNG, GIF, and MPEG4 file format.
  2. Vector graphics (uses points, lines, curves and other shapes). Vector graphics are used in the SVG, EPS, PDF or AI graphic file formats.

So if you need to use an image stored in SVG File in your Xcode I would suggest:

  1. Convert SVG file to PDF. I used https://document.online-convert.com/convert/svg-to-pdf

  2. Use Xcode to manage you PDF file.

Iurie
  • 21
  • 1
0

You can use this pod called 'SVGParser'. https://cocoapods.org/pods/SVGParser.

After adding it in your pod file, all you have to do is to import this module to the class that you want to use it. You should show the SVG image in an ImageView.

There are three cases you can show this SVGimage:

  1. Load SVG from local path as Data
  2. Load SVG from local path
  3. Load SVG from remote URL

You can also find an example project in GitHub: https://github.com/AndreyMomot/SVGParser. Just download the project and run it to see how it works.

0

Here is objective c solution

- (void)loadSVG:(NSString *)url {
if (url.length == 0) return;
[[[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:url]
                            completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    NSHTTPURLResponse *httpURLResponse = (NSHTTPURLResponse *) response;
    if (error == nil && [response.MIMEType hasPrefix:@"image"] && httpURLResponse.statusCode == 200)
    {
        SVGKImage *receivedIcon = [SVGKImage imageWithData:data];
        dispatch_async(dispatch_get_main_queue(), ^{
            imageView.backgroundColor = [UIColor clearColor];
            imageView.image = receivedIcon.UIImage;
        });
        
    } else {
        NSLog(@"error %@ ", error.localizedDescription);
    }
}] resume];

}

GNChishti
  • 39
  • 10