如何在iOS(Swift)中从App Bundle的嵌套文件夹动态加载图片
如何在iOS(Swift)中从App Bundle的嵌套文件夹动态加载图片
嘿,这个需求我做项目时刚好碰到过,太懂你不想硬编码一堆图片路径的麻烦了!下面给你一套实用的Swift方案,完美适配你这种嵌套文件夹的结构:
第一步:先确保Xcode里的文件夹配置正确
首先要注意,你拖入Xcode的Stickers文件夹,一定要选择Create folder references(而不是Create groups),这样打包到App Bundle里时才会完整保留原有的嵌套目录结构,不然Xcode会把所有图片都平铺在根目录下,遍历逻辑就失效了。
第二步:写一个Bundle扩展来遍历目录
我封装了一个Bundle的扩展方法,可以递归遍历指定目录下的所有图片文件,自动收集它们的完整路径:
import UIKit extension Bundle { /// 递归获取指定目录下的所有图片路径 /// - Parameter directoryName: 要遍历的根目录名称(比如"Stickers") /// - Returns: 所有图片文件的完整路径数组 func getAllImagePaths(inDirectory directoryName: String) -> [String] { // 先获取目标目录的URL guard let directoryURL = self.url(forResource: directoryName, withExtension: nil) else { print("⚠️ 找不到指定目录:\(directoryName),请检查文件夹引用配置") return [] } var imagePaths: [String] = [] do { // 获取目录下的所有内容,包括子目录,跳过隐藏文件 let contents = try FileManager.default.contentsOfDirectory( at: directoryURL, includingPropertiesForKeys: [.isDirectoryKey], options: .skipsHiddenFiles ) for itemURL in contents { // 判断当前项是目录还是文件 let isDirectory = try itemURL.resourceValues(forKeys: [.isDirectoryKey]).isDirectory ?? false if isDirectory { // 如果是子目录,递归调用自身 let subDirName = itemURL.lastPathComponent let subDirPaths = getAllImagePaths(inDirectory: "\(directoryName)/\(subDirName)") imagePaths.append(contentsOf: subDirPaths) } else { // 过滤出图片格式的文件,可根据需求扩展支持的格式 let allowedExtensions = ["png", "jpg", "jpeg", "gif", "heic"] if let fileExt = itemURL.pathExtension.lowercased(), allowedExtensions.contains(fileExt) { imagePaths.append(itemURL.path) } } } } catch { print("❌ 遍历目录出错:\(error.localizedDescription)") return [] } return imagePaths } }
第三步:在你的代码中调用并使用
拿到路径数组后,你可以把它们转换成UIImage对象,直接用在列表或网格控件里:
class StickerViewController: UIViewController { var stickerImages: [UIImage] = [] override func viewDidLoad() { super.viewDidLoad() // 获取所有贴纸图片的路径 let allImagePaths = Bundle.main.getAllImagePaths(inDirectory: "Stickers") // 把路径转换成UIImage(用compactMap过滤掉加载失败的图片) stickerImages = allImagePaths.compactMap { UIImage(contentsOfFile: $0) } // 之后就可以把stickerImages数组绑定到你的UICollectionView或UITableView数据源啦 print("总共加载了\(stickerImages.count)张图片") } }
一些需要注意的小细节
- 文件名大小写:iOS真机的文件系统是区分大小写的,Xcode里的文件名如果是
Cat.png,代码里找cat.png会加载失败,所以尽量保持命名统一(比如全小写)。 - 图片格式扩展:如果你的项目用到了其他格式的图片(比如WebP),可以在
allowedExtensions数组里添加对应的后缀。 - 性能考量:如果图片数量特别多,建议把遍历操作放在后台线程执行,避免阻塞主线程影响UI响应。
内容来源于stack exchange
相关产品推荐
相关产品推荐

