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 extensi
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
}()
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 ...
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
}
}
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)
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
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.