[Update]
My way to passing UIImage was wrong. It is impossible because I would never know the instance of view controller which I have to pass an UIImage data. Instead of Using protocol, I share UIImage array using AppDelegate.swift. It worked fine.
======
I’m new to Swift and I need help. This is what I would like to implement :
I used ‘Tabman’ library and there are two tab view controller - FirstTabViewController, SecondTabViewController.
There are one UIImageView and two UIButtons on FirstTabViewController.
There is an UICollectionView on SecondTabViewController. The collection view shows images.
I can download an Image from The Dog API server whenever I pressed ‘Get an Image’ Button.
I can also see the image on UIImageView what I brought from The API.
When I pressed ’Save an Image’ the Delegate should be activated but It seems not. I can see any images on collection view on SecondTabViewController. Also I tried to print some message on Console when delegate is activated, But the message is never came out. I don’t know how to fix it!
I tried to save Instance of View Controller with Appdelegate. I already searched on StackOverflow about How I can specify which instance of view controller will be delegated to. There are some answers say use segue/prepare(). But It looks complicated because the built-in Segway is already created while using Tabman.
I want to find a way to Passing UIImage data thru Delegate. Without create any new segue.
- Here is Delegate protocol code:
import UIKit
protocol ImageDelegate {
func sendImage(with image: UIImage)
}
- Here is TabManViewController code: *It's a view controller that declare Tabman's tab views. *It saves instance of view controllers on Appdelegate property.
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
}
}
- Here is FirstTabViewController code:
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()
}
}
- Here is SecondTabViewController code:
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])
}
}