You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 11:03:05