0

there is this project im working on, but there is a problem with the element in the viewcontroller of my storyboard which i want to change its property from another class! my first approach was instantiating an object from the viewcontroller in my second class! which returns nil at runtime!

        func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
//        let mainstampvc = MainStampVc().storyboard?.instantiateViewController(withIdentifier: "mainstampvc") as? MainStampVc
//        mainstampvc?.setstampimage(imageURL: list_images[indexPath.row])
        
        let msvc = mainstampvc()
        mainstampvc?.setstampimage(imageURL: list_images[indexPath.row])
    }

my second approache was instantiate the whole viewcontroller again in my second class which does nothing.

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let mainstampvc = MainStampVc().storyboard?.instantiateViewController(withIdentifier: "mainstampvc") as? MainStampVc
    mainstampvc?.setstampimage(imageURL: list_images[indexPath.row])
}

the whole thing i wanted is when i click on my uicollectionviewcell change the background of one of my MainViewcontroller views. here is all my classes

viewcontroller.swift

import Foundation
import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var stampholder: UIView!
    @IBAction func TextViewButton(_ sender: Any) {
        removerSubViews()
        addSubView(ViewName: "text")
    }
    @IBAction func AViewButton(_ sender: Any) {
        removerSubViews()
        addSubView(ViewName: "mohr")
    }
    @IBAction func BorderViewButton(_ sender: Any) {
    }
    @IBAction func DlViewButton(_ sender: Any) {
    }
    @IBOutlet weak var holderView: UIView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        addSubView(ViewName: "mohr")
        let mainstampvc = self.storyboard?.instantiateViewController(withIdentifier: "mainstampvc")
        let mainstampview = mainstampvc?.view
        mainstampview?.frame = stampholder.frame
        stampholder.addSubview((mainstampview)!)
    }
    func removerSubViews(){
            for view in self.holderView.subviews{
                view.removeFromSuperview()
            }
    }
    func addSubView(ViewName: String)
    {
        if let subview = Bundle.main.loadNibNamed(ViewName, owner: self, options: nil)?.first as? UIView {
            self.holderView.addSubview(subview);
        }
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

mohrcollectionview.swift

import Foundation
import UIKit

class MohrCollectionViewController: UIView,UICollectionViewDataSource,UICollectionViewDelegate{
    var mohrPath: String = ""
    var fileManager: FileManager!
    var list_images : [String] = []
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        fileManager = FileManager.default
        let currentDir = Bundle.main.resourcePath
        mohrPath = currentDir!
        let mohrsPath = try? fileManager.contentsOfDirectory(atPath: mohrPath + "/mohr")
        list_images = mohrsPath!
    }
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int{
        return list_images.count
    }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        collectionView.register(UINib(nibName: "mohrcell", bundle: nil), forCellWithReuseIdentifier: "mohrcell")
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "mohrcell", for: indexPath) as! mohrCellController
        let image = UIImage(named: list_images[indexPath.row])
        cell.cellimage.image = image
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let mainstampvc = MainStampVc().storyboard?.instantiateViewController(withIdentifier: "mainstampvc") as? MainStampVc
        mainstampvc?.setstampimage(imageURL: list_images[indexPath.row])
    }

}

mainstampvc.swift

import Foundation
import UIKit

class MainStampVc: UIViewController{
    

    @IBOutlet weak var stampimage: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
        setstampimage(imageURL: "golbanafsh.png")
    }
    public func setstampimage(imageURL: String)
    {
        stampimage.image = UIImage(named: imageURL)
    }
}

any help would be appreciated

2

so here is my code with delegation but still nothing :(

//
//  MohrCollectionViewController.swift
//  Mohrem
//
//  Created by shayan rahimian on 12/18/17.
//  Copyright © 2017 shayan rahimian. All rights reserved.
//
import Foundation
import UIKit



class MohrCollectionViewController: UIView,UICollectionViewDataSource,UICollectionViewDelegate,UpdateBackgroundDelegate{
    var updatedelegate:UpdateBackgroundDelegate? = nil
    func updateBackground(imageURL: String) {
        print("mohr update back ground e balaE")
        if updatedelegate == nil {
            print("no delegate")
        }else{
            updatedelegate?.updateBackground(imageURL: imageURL)
        }
    }
    var mohrPath: String = ""
    var fileManager: FileManager!
    var list_images : [String] = []
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        fileManager = FileManager.default
        let currentDir = Bundle.main.resourcePath
        mohrPath = currentDir!
        let mohrsPath = try? fileManager.contentsOfDirectory(atPath: mohrPath + "/mohr")
        list_images = mohrsPath!
    }
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int{
        return list_images.count
    }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        collectionView.register(UINib(nibName: "mohrcell", bundle: nil), forCellWithReuseIdentifier: "mohrcell")
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "mohrcell", for: indexPath) as! mohrCellController
        let image = UIImage(named: list_images[indexPath.row])
        cell.cellimage.image = image
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        self.updateBackground(imageURL: list_images[indexPath.row])
    }
    
}



//
//  MainStampvc.swift
//  Mohrem
//
//  Created by shayan rahimian on 12/19/17.
//  Copyright © 2017 shayan rahimian. All rights reserved.
//

import Foundation
import UIKit

protocol UpdateBackgroundDelegate : class {
    func updateBackground(imageURL: String)
}
class MainStampVc: UIViewController{

    @IBOutlet weak var stampimage: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
        updateBackground(imageURL: "biggolabi.png")
        
    }
    func updateBackground(imageURL: String) {
        // update your background in this funcion
        print("extension")
        print(imageURL)
        stampimage.image = UIImage(named: imageURL)
    }

}

am i doing anything wrong?

Community
  • 1
  • 1
sci3nt15t
  • 93
  • 1
  • 8
  • What is the structure of the app? Do you want to change color on first controller from second? Do you have push hierarchy, modal...? – Stefan Dec 19 '17 at 14:54
  • @sci3nt15t please be clear on what is issue. please show relevant code. This will help in better understanding of problem, and a quick solution. – Tushar Sharma Dec 19 '17 at 14:59
  • Part of your problem is that you have a custom `UIView` that you call a controller and which supplies data to another view. That makes the structure hard to work with. – Phillip Mills Dec 19 '17 at 15:27
  • Could you share your sample project and proper requirement? Change color of MainStampVc or MohrCollectionViewController ?? – Jeetendra Kumar Dec 19 '17 at 15:29
  • @Stefan What im actually dealing with is i want to change the background image of my mainstampVc from mohrcollectionviewcontroller which is not a viewcontroller but a uiview! – sci3nt15t Dec 20 '17 at 07:04
  • Then the easiest way is to delegate it from that UIView. – Stefan Dec 20 '17 at 12:59

2 Answers2

1

You could pass a UIViewController reference to the MohrCollectionViewController(you should call this MohrCollectionView to avoid confusion) at the time you construct it. Then whenever you need to update the background you call the relevant function on the reference.

class ViewController : UIViewController {
    ...
    override func viewDidLoad() {
        ...
        let view = addSubView(ViewName: "mohr")
        view?.vc = self
    }
    func addSubView(ViewName: String) -> UIView?
    {
        if let subview = Bundle.main.loadNibNamed(ViewName, owner: self, options: nil)?.first as? UIView {
            self.holderView.addSubview(subview);
            return subview
        }
    }
    return nil
}

class MohrCollectionView {

     func updateVcBackground() {
         vc?.updateBackground()
     }
     var vc : ViewController? = nil
}

A cleaner way to do this is use a delegate. A delegate uses a protocol to define an interface between two classes.

protocol UpdateBackgroundDelegate : class {
    func updateBackground()
}

class ViewController : UIViewController, UpdateBackgroundDelegate {
    ...
    override func viewDidLoad() {
        ...
        let view = addSubView(ViewName: "mohr")
        view?.updateBackgroundDelegate = self
    }
    func updateBackground() {
        // update your background in this funcion
    }
}

class MohrCollectionView {

     func updateVcBackground() {
         updateBackgroundDelegate?.updateBackground()
     }
     var updateBackgroundDelegate : UpdateBackgroundDelegate? = nil
}
adamfowlerphoto
  • 2,708
  • 1
  • 11
  • 24
  • thank you so much for your help, i totally forgot about the delegation! but now im having problem with that, i update my question, will you please help me? – sci3nt15t Dec 20 '17 at 08:30
0

For making the delegate work do the following:

  1. Declare the delegate first like in Collection View Class

    protocol UpdateBackgroundDelegate : class {
    func updateBackground(imageURL: String)
    }
    
  2. Create a variable like

    var updateDelegate: UpdateBackgroundDelegate?
    

and paste it below your collectionView class from where you want to trigger changing background colour

  1. In the collection view selection delegate, add this line of code

    updateDelegate.updateBackground(imageUrl: yourUrl) 
    
  2. In the View, where colour change has to take place, create your collectionView instance and add this line of code

    collectionView.updateDelegate = self 
    
  3. At last add this extension

    class ViewController :UpdateBackgroundDelegate {
       func updateBackground(imageUrl: yourUrl) {
          //write code to load image from url
       }
    }
    
manish_kumar
  • 260
  • 2
  • 12