将数据从一个 Tab Bar View Controller child(我想?)传递到另一个 TabBarVC 的 Collection 视图? (以编程方式)

Passing data from child (I think?) of one Tab Bar View Controller to Collection View of another TabBarVC? (Programmatically)

我正在以编程方式构建基于选项卡栏控制器的应用程序。我正在尝试弄清楚如何将数据从我认为是一个选项卡栏视图控制器的 child(在 viewControllers[1] 顶部额外显示 VC)发送到collection viewControllers[0] 处的另一个选项卡栏 VC 的视图。我在这里阅读了很多条目,但 none 似乎对我有用,或者我不理解它们。

基本上,在 viewControllers[1] 的 VC 中,我通过在主选项卡 VC.

中实现此代码实现了一个自定义的全屏摄像头
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
     if viewControllers?.firstIndex(of: viewController) == 1 {
         present(cameraVC, animated: true, completion: nil)
     }
return true 
}

然后在那个 VC 中,我正在捕获图像并使用 present(editVC) 将新的编辑VC 堆叠在上面,以将捕获的照片显示为以及一些编辑工具。我说 "stacking" 尽管我不知道这些在这样呈现时是否真的成为层次结构的一部分?可以澄清一下。从那个编辑 VC,我正在执行编辑并将文件保存到 documentsDirectory。一切正常,图像成功保存。但是我被困的地方是获取我保存回我的 collection view VC at viewControllers[0] 的照片的路径地址,这样我就可以用照片填充它的单元格.

我已经尝试创建一个委托,但我意识到我无法将 viewControllers[0] 设置为 viewControllers[1] 的(第一个或第二个?)child 的委托。 (我不清楚上面的代码是否本质上使 cameraVC 成为 viewControllers[1] 本身的 child。)或者它可以 I/is 推荐吗?

然后我尝试创建一个状态 class,其中包含一个 URL 数组(用于保存文件的路径),editVC 和 viewControllers[0] collection 视图可以读取。但我似乎无法获得 editVC 来更新该数组。我怀疑我无意中创建了 "state" 的多个实例。 class 来自我每个不同的 VCs?

我有太多代码,我不确定要做什么 post 但希望这是相关的:

状态class:

class StatePaths {
  var urls = [URL]()
}

编辑中VC

//  declaration at the beginning of the class

    var statePaths: StatePaths?

// In the save func:

 let imageName = UUID().uuidString
        let imagePath = getDocumentsDirectory().appendingPathComponent(imageName)

        if let jpegData = image.jpegData(compressionQuality: 0.8) {
            try? jpegData.write(to: imagePath)
            self.statePaths.urls.append(imagePath)
            self.dismiss(animated: true)
        }

在viewControllers的collection视图中[0]

var statePaths = StatePaths()

// In the cellForItem func:

let path = statePaths[indexPath.item]
if let image = UIImage(contentsOfFile: path.path) {
            cell.imageView.image = image
}

我还实现了一些显示图像正在保存的打印语句,但它们没有填充 statePaths class。我还在 collection VC.

的 ViewWillAppear 上实现了 collectionView.reloadData()

我们将不胜感激任何关于这些方法或任何其他方法的帮助。

I suspect I am inadvertently creating multiple instances of that "state". class from each of my different VCs?

是的,"statePaths"是多个实例,没必要用。您需要在 viewControllers[0].

处获取保存的图像

此外,更明确的方法是将此代码与单独的模型或服务分离。 例如:

struct ImageStorage {

    static var documentsDirectory: String {
        return NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
    }

    static var imagesDirectory: String {
        let imagesDirectory = documentsDirectory + "/images/"
        if !FileManager.default.fileExists(atPath: imagesDirectory) {
            try? FileManager.default.createDirectory(atPath: imagesDirectory, withIntermediateDirectories: true, attributes: nil)
        }
        return imagesDirectory
    }

    static var images: [UIImage] {
        guard let paths = try? FileManager.default.contentsOfDirectory(atPath: imagesDirectory) else {
            return []
        }
        let images = paths.compactMap { UIImage(contentsOfFile: imagesDirectory + [=10=]) }
        return images
    }

    static func save(_ image: UIImage) {
        let imageName = UUID().uuidString
        let imagePath = imagesDirectory + imageName
        let imageUrl = URL(fileURLWithPath: imagePath)

        guard let jpegData = image.jpegData(compressionQuality: 0.8) else {
            return
        }
        try? jpegData.write(to: imageUrl)
    }
}

然后在viewController中使用:

ImageStorage.save(image)
ImageStorage.images

更新。关于传递数据的问题:视情况而定。

在某些情况下,您可以使用委托、tabBarViewController 堆栈、NotificationCenter 等将数据传递给 viewController

但在其他情况下更容易使用单例来临时存储数据。 正如我所见, viewController 之间的 link 在你的情况下并不那么明显。所以首选单例。

例如:

class StatePaths {    
    static let shared = StatePaths()    
    private init() {}

    var urls = [URL]()
}

StatePaths.shared.urls = urls
let urls = StatePaths.shared.urls