MessageAppExtension:如何将资产中的贴纸图像加载到MSStickerBrowserView?

时间:2016-09-16 22:52:31

标签: ios swift message swift3 ios10

好吧,我知道这对每个人来说都是新的,但我认为这是一个简单的概念 - 我在这里关注这个以制作自定义贴纸消息应用扩展程序:

https://code.tutsplus.com/tutorials/create-an-imessage-app-in-ios-10--cms-26870

我已经完全复制了一切,并且我正在尝试创建一个基本的MSStickerBrowserView显示(然后使用逻辑进行过滤,但还没有尝试过)我在我的资源文件夹中有贴纸pngs:

enter image description here

教程没有从资产中加载,而是仅从他们的项目中加载,无论他们的代码是旧的,如:

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

我找不到任何相关内容。如何在应用程序中以编程方式显示我的贴纸?

错误:

enter image description here

这些是我试图加载的图像,无论其名称如何:

enter image description here

3 个答案:

答案 0 :(得分:4)

教程不使用资产目录的原因是,在调用捆绑包上的urlForResource方法时,无法为放置在.xcassets文件夹中的图像获取有效的fileURL。

您需要像添加到应用中的其他文件一样单独添加资源。在该点上调用bundle上的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")

请注意,不要在文件夹名称的开头包含正斜杠('/')。

答案 1 :(得分:1)

只需替换" resourceUrl"用:

let url = Bundle.main.url(forResource: "Sticker \(i)", withExtension: "png")

代码在Swift 3中被替换。

答案 2 :(得分:0)

您可以将图像放在像这样的文件夹中(XCODE Viewport):

enter image description here

它使事情更有条理,但不需要像将它们放在.xcasset中一样多的代码。

可以通过创建新组来完成,而不是通过(右键单击消息扩展并单击“新建组”)创建.xcasset:

enter image description here

可以像下面这样调用以下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上发现它并且它非常有用)