如何使用 swift 显示 .svg 图像

Posted

技术标签:

【中文标题】如何使用 swift 显示 .svg 图像【英文标题】:How to display .svg image using swift 【发布时间】:2016-06-12 00:53:07 【问题描述】:

我有一个 .svg 图像文件,我想在我的项目中显示。

我尝试使用 UIImageView,它适用于 .png 和 .jpg 图像格式,但不适用于 .svg 扩展名。有没有办法使用 UIWebView 或 UIImageView 显示 .svg 图像?

【问题讨论】:

***.com/questions/24149785/… 和 yberdnikov.github.io/2014/06/18/… github.com/SVGKit/SVGKit 这和UIImageView有一个非常相似的API 或者,您可以将 svg 转换为 jpg 或 png 并使用该图像...而不是浪费时间搜索 svg 支持。 是否有任何代码可以快速将 .svg 图像转换为 jpg? 你也可以试试 Snowflake github.com/onmyway133/snowflake 【参考方案1】:

Swift 中没有对 SVG 的内置支持。 所以我们需要使用其他库。

swift 中的简单 SVG 库是:

1)SwiftSVG图书馆

它为您提供了更多选项来导入为 UIView、CAShapeLayer、Path 等

要修改您的 SVG 颜色并导入为 UIImage,您可以将我的扩展代码用于以下链接中提到的库,

点击此处了解如何使用SwiftSVG 库:Using SwiftSVG to set SVG for Image

|或|

2)SVGKit图书馆

2.1) 使用pod安装:

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

2.2) 添加框架

转到应用设置 -> 常规选项卡 -> 向下滚动到链接的框架和库 -> 点击加号图标 -> 选择 SVG.framework

2.3) 将 Objective-C 添加到 Swift 桥接文件 bridging-header.h :

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

2.4) 在 Project 中创建 SvgImg 文件夹(以便更好地组织)并在其中添加 SVG 文件。

注意:添加内部资产文件夹将不起作用,SVGKit 仅在项目文件夹中搜索文件

2.5) 在您的 Swift 代码中使用如下:

import SVGKit

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

注意:SVGKit 会自动将扩展名“.svg”附加到您指定的字符串

let namSvgImgVyuVar = SVGKImageView(SVGKImage: namSvgImgVar)

let namImjVar: UIImage = namSvgImgVar.UIImage

还有更多选项供您初始化 SVGKImage 和 SVGKImageView

您还可以探索其他课程

    SVGRect
    SVGCurve
    SVGPoint
    SVGAngle
    SVGColor
    SVGLength

    and etc ...

【讨论】:

很好的解释。但是你应该/不能直接使用SVGKImageView。而是必须使用 SVGKFastImageViewSVGKLayeredImageView 在链接的框架和库中添加SVGKit.framework【参考方案2】:

试试这个代码

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

【讨论】:

这里的 webview 到底是什么?它给了我这个致命错误:unwrapping an Optional value 时意外发现 nil webview 显然是 UIWebView。 Ankit Vij,如果它解包为 nil,则可能意味着路径错误,找不到文件。 @SmallChess UIWebView 显然已被弃用。 这是一个很好且简单的解决方案。但是,可以在代码中的某处指定 webView var。只是为了让这个例子更好一点。更好的缩进也会让我的大脑更快乐地阅读它。【参考方案3】:

例如,您可以使用SVGKit。

1) 按照说明进行集成。拖放 .framework 文件既快速又简单。

2) 确保您有一个 Objective-C 到 Swift 的桥接文件 bridging-header.h,其中包含导入代码:

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

3) 使用这样的框架,假设dataFromInternet是NSData,之前是从网络上下载的:

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

该框架还允许从其他不同来源初始化 SVGKImage,例如,当您提供 URL 时,它可以为您下载图像。但在我的情况下,它会在无法访问 url 的情况下崩溃,所以我自己管理网络会更好。更多信息here。

【讨论】:

谢谢...我也已经试过了。它是一种下载和显示 .svg 图像的简单方法 感谢框架的链接。非常适合我 非常非常慢的框架。显示大小为 1M 的本地 svg 需要 25 秒【参考方案4】:

您可以在 .xcassets 中添加新符号图像集,然后您可以在其中添加 SVG 文件

并像图像一样使用它。

注意:这不适用于所有 SVG。你可以看看apple documentation

【讨论】:

这仅适用于非常特定的 SVG 文件子集,参见。 developer.apple.com/documentation/uikit/uiimage/… 感谢@DirtyHenry,我在回答中添加了注释。【参考方案5】:

SVG 文件支持已添加到 Xcode 12。

【讨论】:

知道这是如何工作的吗?我尝试将 SVG 文件添加到 .xcassets 文件中,但它只是给出了一个错误。 您使用的是哪个 Xcode?它在 .xcassets 中对我有用 也可以用于 xcode 12,它们提供了向后兼容性。【参考方案6】:

我从 URL 在 UIImageView 中显示 .svg 的解决方案。 你需要安装SVGKit pod

然后像这样使用它:

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

或者您可以使用扩展程序进行异步下载

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


使用方法:

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

imageview.downloadedsvg(from: svg)

【讨论】:

【参考方案7】:

Swift 3.0 版本:

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

第三方库

https://github.com/exyte/Macaw

https://github.com/mchoe/SwiftSVG

UIWebView 和 WKWebView 加速器加载更快

https://github.com/bernikovich/WebViewWarmUper

【讨论】:

webView 是打开 .SVG 文件的唯一方法,我想在滚动视图中加载多个 SVG 文件。 在运行时创建html文本或使用tableview和webview 如何在ImageView中使用? @KrutarthPatel 你可以在 UIView 中使用第三方库 @KrutarthPatel 需要再次检查我的答案,以便 UIWebView 和 WKWebView 助推器加载更快【参考方案8】:

如果您想使用 WKWebView 加载来自 URLRequest 的 .svg 图像,您可以像这样简单地实现它:

斯威夫特 4

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

它比其他方法简单得多,而且您还可以将 .svg 字符串保存在某个地方以便稍后加载,甚至在需要时离线。

【讨论】:

一个不错且非常干净的解决方案。 我如何让比例居中并填充框架,而不是它添加的滚动视图? 我相信你只能通过在 WKWebView 中注入 javascript 代码来实现这一点,或者在 svg 加载后在某些 WKNavigationDelegate 方法处更改配置。 Swift 编译器不会为我接受 String(contentsOf: request),而是它想要一个 URL 的请求。对于 baseURL,它还需要一个 url,而不是请求。【参考方案9】:

您可以将图像保存为字符串并使用 WKWebView 显示它们:

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

【讨论】:

谢谢!你让我明白它是如何工作的。现在我只需要弄清楚如何保存来自 POST 请求的 .svg 字符串。 你有这个使用的 repo 例子吗? 已经尝试过gist.github.com/lfcj/a08a84eb0fc20f92849dbb49e6dfa435,但它不起作用:(这对你有用吗,@nanvel?【参考方案10】:

这是一个简单的类,可以在UIView中显示SVG图像

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
    

【讨论】:

有人试过这个吗? @cybergeeeek 我之前在 Objective-C 中做过几乎相同的解决方案,所以这应该可以工作。唯一的缺点是网页视图的加载时间很慢,所以图片会在屏幕加载半秒后出现。【参考方案11】:

SVGKit 帮助我从 URL 获取图像。

首先,在您的 Podfile 中添加 pod 'SVGKit'

其次,import SVGKit 进入你的班级。

第三,创建一个SVGImage对象。

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

最后,将此图像添加到您的 UIImageView。

yourImageView.image = mySVGImage.uiImage

【讨论】:

【参考方案12】:

据我所知,有两种不同的图形格式:

    光栅图形(使用位图)并用于 JPEG、PNG、APNG、GIF 和 MPEG4 文件格式。 矢量图形(使用点、线、曲线和其他形状)。矢量图形用于 SVG、EPS、PDF 或 AI 图形文件格式。

因此,如果您需要在 Xcode 中使用存储在 SVG 文件中的图像,我建议:

    将 SVG 文件转换为 PDF。我用https://document.online-convert.com/convert/svg-to-pdf

    使用 Xcode 管理您的 PDF 文件。

【讨论】:

【参考方案13】:

要渲染 SVG 文件,您可以使用 Macaw。 Macaw 还支持转换、用户事件、动画和各种效果。

您可以使用零行代码渲染 SVG 文件。欲了解更多信息,请查看这篇文章:Render SVG file with Macaw。

免责声明:我隶属于这个项目。

【讨论】:

能否请您阅读How to offer personal open-source libraries?这显然是您自己的项目,请在您的帖子中披露。 我尝试了 Macaw,但 SVG 的质量太差了【参考方案14】:

您可以使用这个名为“SVGParser”的 pod。 https://cocoapods.org/pods/SVGParser.

将它添加到您的 pod 文件中后,您所要做的就是将该模块导入到您要使用的类中。您应该在 ImageView 中显示 SVG 图像。

您可以在三种情况下显示此 SVG 图像:

    从本地路径加载 SVG 作为数据 从本地路径加载 SVG 从远程 URL 加载 SVG

您还可以在 GitHub 中找到示例项目:https://github.com/AndreyMomot/SVGParser。 只需下载项目并运行它,看看它是如何工作的。

【讨论】:

这个库使用了在 ios 12 上被弃用的 UIWebView...

以上是关于如何使用 swift 显示 .svg 图像的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Jupyter Notebook 的同一行上显示两个 SVG 图像

尝试显示 SVG <图像> 时如何修复 403 错误?

如何在 React Native 上显示 SVG 文件?

如何使用 SVG 更改悬停时的图像源?

如何使用 React 组件在 UI 中显示 svg 图标(.svg 文件)?

如何使用 Swift 的逻辑动态显示图像和文本?