MessageAppExtension:如何将贴纸图像从资产加载到 MSStickerBrowserView?
Posted
技术标签:
【中文标题】MessageAppExtension:如何将贴纸图像从资产加载到 MSStickerBrowserView?【英文标题】:MessageAppExtension: how to load sticker images from assets to MSStickerBrowserView? 【发布时间】:2016-09-16 22:52:31 【问题描述】:好吧,我知道这对每个人来说都是新的,但我认为这将是一个简单的概念 - 我在这里按照这个来制作自定义贴纸消息应用扩展:
https://code.tutsplus.com/tutorials/create-an-imessage-app-in-ios-10--cms-26870
我已经完全复制了所有内容,并正在尝试创建一个基本的 MSStickerBrowserView 显示(然后使用逻辑过滤,但尚未尝试过)我在我的资产文件夹中的贴纸 png:
该教程似乎不是从资产加载的,而是从他们的项目加载的,无论他们的代码是否像这里一样旧:
var stickers = [MSSticker]()
func loadStickers()
for i in 1...2
if let url = Bundle.main.urlForResource("Sticker \(i)", withExtension: "png") //ERROR!!
do
let sticker = try MSSticker(contentsOfFileURL: url, localizedDescription: "")
stickers.append(sticker)
catch
print(error)
我得到了错误
Bundle 没有成员 URLforResource
我在这方面找不到任何东西。如何在应用程序中以编程方式显示我的贴纸?
错误:
这些是我尝试加载的图像,无论其名称如何:
【问题讨论】:
好的,但是看看我的问题是否有错误 - 我怎样才能用这个加载我的资产文件夹的内容? 抱歉,新手 在 Swift 3 中应该是 Bundle.main.url(forResource: String?, withExtension: String?) 对不起,我提供了错误的陈述。立即检查。 好的,这行得通,但是我如何将我的贴纸包文件夹中的所有 png 加载到资产中?我在上面添加了一张图片 【参考方案1】:教程不使用资产目录的原因是,在调用捆绑包上的 urlForResource 方法时,您无法为放置在 .xcassets 文件夹中的图像获取有效的 fileURL。
您需要像添加其他文件一样单独添加资产。此时在捆绑包上调用 pathForResource 或 urlForResource 将不再返回 nil。
编辑:这是一个函数,它将获取文件夹名称,遍历其内容并返回 [MSSticker]?基于它的发现
func createStickers(from folderName: String) -> [MSSticker]?
guard
let path = Bundle.main.resourcePath
else return nil
var stickers = [MSSticker]()
let folderPath = "\(path)/\(folderName)"
let folderURL = URL(fileURLWithPath: folderPath)
//get a list of urls in the chosen directory
do
let imageURLs = try FileManager.default.contentsOfDirectory(at: folderURL,
includingPropertiesForKeys: nil,
options: .skipsHiddenFiles)
//loop through the found urls
for url in imageURLs
//create the sticker and add it, or handle error
do
let sticker = try MSSticker(contentsOfFileURL: url, localizedDescription: "yourDescription")
stickers.append(sticker)
catch let error
print(error.localizedDescription)
catch let error
print(error.localizedDescription)
//return nil if stickers array is empty
return stickers.isEmpty ? nil : stickers
这应该让你只需调用它并得到你想要的:
let stickers = createStickers(from: "YourFolderName")
请注意不要在文件夹名称的开头包含正斜杠 ('/')。
【讨论】:
是的,我想通了,但我想引入一个包含特定图像的文件夹并遍历它们(不仅仅是单个图像)。到目前为止,我无法引入文件夹,因为文件夹没有任何扩展名,因此您无法使用 urlForResource - 我该怎么做? @skyguy - 我添加了一个功能来完成你所追求的。我已经在一个示例项目中对其进行了测试,并且能够遍历文件夹并使用仅添加到扩展程序中的图像创建贴纸。 我把它放在扩展文件夹中,一切正常 它是一个 .xcassets 文件夹吗? 刚刚再次运行我的...工作正常,但在尝试访问不存在或资产文件夹的文件夹时收到相同的错误消息。我建议查看模拟器目录并按照路径验证它是否确实存在【参考方案2】:只需将“resourceUrl”替换为:
let url = Bundle.main.url(forResource: "Sticker \(i)", withExtension: "png")
代码在 Swift 3 中被替换。
【讨论】:
【参考方案3】:您可以将图像放在这样的文件夹中(XCODE Viewport):
它使事情更有条理,但不需要像将它们放在 .xcasset 中那样多的代码。
可以通过创建一个新组而不是通过(右键单击消息扩展并单击新组)创建一个.xcasset来完成:
以下 StickerBrowserView 的代码可以这样调用:
import UIKit
import Messages
class StickerBrowserViewController: MSStickerBrowserViewController
var stickers = [MSSticker]()
func changeBrowserViewBackgroundColor(color: UIColor)
stickerBrowserView.backgroundColor = color
func loadStickers()
createSticker(asset: "1", localizedDescription:"grinning face")
createSticker(asset: "2", localizedDescription:"grimacing face")
createSticker(asset: "3", localizedDescription:"grinning face with smiling eyes")
createSticker(asset: "4", localizedDescription:"face with tears of joy")
createSticker(asset: "5", localizedDescription:"smiling face with open mouth")
createSticker(asset: "6", localizedDescription:"smiling face with open mouth and smiling eyes")
func createSticker(asset: String, localizedDescription: String)
guard let stickerPath = Bundle.main.path(forResource:asset, ofType:"png") else
print("couldn't create the sticker path for", asset)
return
// we use URL so, it's possible to use image from network
let stickerURL = URL(fileURLWithPath:stickerPath)
let sticker: MSSticker
do
try sticker = MSSticker(contentsOfFileURL: stickerURL, localizedDescription: localizedDescription)
// localizedDescription for accessibility
stickers.append(sticker)
catch
print(error)
return
override func numberOfStickers(in stickerBrowserView: MSStickerBrowserView) -> Int
return stickers.count
override func stickerBrowserView(_ stickerBrowserView: MSStickerBrowserView, stickerAt index: Int) -> MSSticker
return stickers[index] as MSSticker
(Ps. 不是我的博客,是在google上找到的,很有用)
【讨论】:
以上是关于MessageAppExtension:如何将贴纸图像从资产加载到 MSStickerBrowserView?的主要内容,如果未能解决你的问题,请参考以下文章