使用 Delegate 将 UIImage 数据传递到另一个视图控制器

问题描述 投票:0回答:1

[更新]

我传递 UIImage 的方式是错误的。这是不可能的,因为我永远不会知道必须传递 UIImage 数据的视图控制器的实例。 我没有使用协议,而是使用 AppDelegate.swift 共享 UIImage 数组。效果很好。

======

我是 Swift 新手,我需要帮助。这就是我想要实现的:

  1. 我使用了“Tabman”库,有两个选项卡视图控制器 - FirstTabViewController、SecondTabViewController。

  2. FirstTabViewController 上有一个 UIImageView 和两个 UIButton。

  3. SecondTabViewController 上有一个 UICollectionView。 集合视图显示图像。

  4. 只要按下“获取图像”按钮,我就可以从 The Dog API 服务器下载图像。

  5. 我还可以在 UIImageView 上看到我从 API 带来的图像。

  6. 当我按下“保存图像”时,委托应该被激活,但似乎没有。我可以在 SecondTabViewController 上的集合视图上看到任何图像。另外,当激活委托时,我尝试在控制台上打印一些消息,但该消息从未显示出来。我不知道如何解决它!

  7. 我尝试使用 Appdelegate 保存视图控制器的实例。我已经在 StackOverflow 上搜索了如何指定将委托给哪个视图控制器实例。有一些答案说使用 segue/prepare()。但看起来很复杂,因为使用 Tabman 时已经创建了内置 Segway。

我想找到一种通过委托传递 UIImage 数据的方法。无需创建任何新的segue。

  1. 这是委托协议代码:
import UIKit

protocol ImageDelegate {
    func sendImage(with image: UIImage)
}
  1. 这是 TabManViewController 代码: *它是一个声明 Tabman 选项卡视图的视图控制器。 *它将视图控制器的实例保存在 Appdelegate 属性上。
import Foundation
import Tabman
import Pageboy

class TabManViewController: TabmanViewController {
    private var viewControllers: Array<UIViewController> = []
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let firstVC = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "FirstTabVC") as! FirstTabViewController
        let secondVC = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SecondTabVC") as! SecondTabViewController
        
        viewControllers.append(firstVC)
        viewControllers.append(secondVC)
        
        let ad = UIApplication.shared.delegate as? AppDelegate
        
        ad?.firstVCInstance = firstVC
        ad?.secondVCInstance = secondVC
        
        self.dataSource = self
        
        // Create bar
        let bar = TMBar.ButtonBar()
        bar.layout.transitionStyle = .snap // Customize
        bar.indicator.weight = .custom(value: 1)
        bar.indicator.tintColor = .black
        // tap center
        bar.layout.alignment = .centerDistributed
        // tap 사이 간격
        bar.layout.interButtonSpacing = 12
        // tap 선택 / 미선택
        bar.buttons.customize { (button) in
            button.tintColor = .gray
            button.selectedTintColor = .black
            button.selectedFont = UIFont.systemFont(ofSize: 16, weight: .medium)
        }
        
        // Add to view
        addBar(bar, dataSource: self, at: .top)
    }
}

//MARK: - Tabman DataSource
extension TabManViewController: PageboyViewControllerDataSource, TMBarDataSource {
    func barItem(for bar: TMBar, at index: Int) -> TMBarItemable {
        let item = TMBarItem(title: "")
        if index == 0 {
            item.title = "Get a dog"
        } else if index == 1 {
            item.title = "Gallery"
        } else {
            item.title = "Page \(index+1)"
        }
        item.image = UIImage(named: "image.png") // ??
        
        return item
    }
    
    func numberOfViewControllers(in pageboyViewController: PageboyViewController) -> Int {
        return viewControllers.count
    }
    
    func viewController(for pageboyViewController: PageboyViewController,
                        at index: PageboyViewController.PageIndex) -> UIViewController? {
        return viewControllers[index]
    }
    
    func defaultPage(for pageboyViewController: PageboyViewController) -> PageboyViewController.Page? {
        return nil
    }
}

  1. 这是 FirstTabViewController 代码:
import Tabman
import UIKit
import Alamofire

class FirstTabViewController: TabmanViewController {    
    var delegate: ImageDelegate?
    var dogImage: UIImage?
    
    @IBOutlet weak var imageView: UIImageView!
    @IBAction func GetImagePressed(_ sender: UIButton) {
        getADog()
    }
    @IBAction func SaveImagePressed(_ sender: UIButton) {
        print("==")
        print("SaveImage Btn Pressed")
        if let safeImage = dogImage {
            delegate?.sendImage(with: safeImage)
        } else {
            print("dogImage is nil")
        }
    }
    private var apiKey: String {
        get {
            guard let filepath = Bundle.main.path(forResource: "Keys", ofType: "plist") else {
                fatalError("Couldn't find file 'Keys.plist'.")
            }
            let plist = NSDictionary(contentsOfFile: filepath)
            guard let value = plist?.object(forKey: "API_KEY") as? String else {
                fatalError("Couldn't find key 'API_KEY' in 'Keys.plist'.")
            }
            return value
        }
    }
    
    //MARK: - View Life Cycle
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

  1. 这是 SecondTabViewController 代码:
import Foundation
import Tabman

class SecondTabViewController: TabmanViewController {
    @IBOutlet weak var collectionView: UICollectionView!
    
    var collectedDogImages = [UIImage]()
    let sectionInsets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
    
    override func viewDidLoad() {
        collectionView.dataSource = self
        collectionView.delegate = self
        
        let ad = UIApplication.shared.delegate as? AppDelegate
        if let firstVCInstance = ad?.firstVCInstance {
            firstVCInstance.delegate = self
        } else {
            print("Error: Can't read firstVCInstance from Appdelegate.")
        }

    }
}

//MARK: - CollectionView
extension SecondTabViewController: UICollectionViewDataSource,
                                   UICollectionViewDelegate,
                                   UICollectionViewDelegateFlowLayout
{
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        print("cell count = \(collectedDogImages.count)") // It says always 0
        return collectedDogImages.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as? UICollectionViewCell
        else {
            return UICollectionViewCell()
        }
        let imageData = collectedDogImages[indexPath.row - 1]
        let appendingView = UIView(frame: CGRect.init())
        let appendingImageView = UIImageView(image: imageData)
        appendingView.addSubview(appendingImageView)

        cell.contentView.addSubview(appendingView)
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let width = collectionView.frame.width
        let height = collectionView.frame.height
        let itemsPerRow: CGFloat = 2
        let widthPadding = sectionInsets.left * (itemsPerRow + 1)
        let itemsPerColumn: CGFloat = 3
        let heightPadding = sectionInsets.top * (itemsPerColumn + 1)
        let cellWidth = (width - widthPadding) / itemsPerRow
        let cellHeight = (height - heightPadding) / itemsPerColumn
        
        return CGSize(width: cellWidth, height: cellHeight)
    }
    
}

//MARK: - InsertImageDelegate
extension SecondTabViewController: ImageDelegate {
    func sendImage(with image: UIImage) {
        //test
        print("=")
        print("secondTab delegate method activated") // Never printed on console
        
        self.collectedDogImages.append(image)
        let itemLocation = self.collectedDogImages.count
        let indexPaths = IndexPath(item: itemLocation, section: 0)
        
        self.collectionView.insertItems(at: [indexPaths])
    }
}

delegates appdelegate pass-data
1个回答
0
投票

您在 FirstTabViewController 中声明了 ImageDelegate 协议的实例,但尚未在其中启动。应该是这样的

FirstTabViewController : UIViewController {
    var delegate: ImageDelegate?

    override func viewDidLoad() {
        super.viewDidLoad()
        delegate = SecondTabViewController()
        /* its best advised to not to create multiple instances of SecondTabViewController for assigning a delegate */                        
    }
    
}

extension SecondTabViewController: ImageDelegate {
    func sendImage(with image: UIImage) {
        // your logic for handling image
    }   
}

您的代表是nil。它不知道“谁”遵守该协议。你需要说它是 SecondTabViewController

© www.soinside.com 2019 - 2024. All rights reserved.