Search code examples
iosswiftuiviewuikituiimage

Add an image to a subclass of UIVIew


I have a UIViewController in which I have set a UIIView as a subview to hold a UIImage in it

class MyVIewController: UIViewController { 

  let myView = MyView()

     override func viewDidLoad() {
            super.viewDidLoad()
            myView.translatesAutoresizingMaskIntoConstraints =  false  
            myView.backgroundColor = .systemPink
           
            view.addSubview(myView)

    } 

  @objc func changeImageFunc(_ sender: Any) {

      //...extra code assigned .image (savedImage)
   myView.setImage(savedImage)

   }
class MyView: UIView {
    
     var imageView: UIImageView
    
    override init(frame: CGRect) {
     
        
        imageView = UIImageView()
        super.init(frame: frame)
        
        addSubview(imageView)

    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")

    }
    
    func setImage(_ image: UIImage) {
         // Set the image for the internal UIImageView
         imageView.image = image
     }
    
}

I tried to assing the imageView property directly in the chaneImageFunc like so

myView.imageView.image = savedImage

But did not work either. How could I show the image saved in my myView class onto MyViewController


Solution

  • It doesn't look like you're ever establishing any auto layout constraints for the UIImageView (or MyView for that matter). Because of this, my guess is that even if the background color of the UIView is showing, the imageView's frame is 0 height and 0 width. You should be able to see this when using the "Debug View Hierarchy" option within Xcode while running your app.

    Debug View Hierarchy

    0 Size

    Here's an example adjusting your code to include auto layout constraints for the view and the imageView which should allow the image to show up properly.

    Edit: When setting up views programmatically, they will default to using autoresizing mask (spring and struts) and translate those to auto layout constraints. To setup programatic auto layout constraints without having them conflict with autoresizing mask (translated to auto layout constraints), you'll want to disable translating authorizing mask to auto layout constraints by setting translatesAutoresizingMaskIntoConstraints to false on the target view.

    class MyViewController: UIViewController {
        
        let myView = MyView()
        
    
        override func viewDidLoad() {
            super.viewDidLoad()
            super.viewDidLoad()
            myView.translatesAutoresizingMaskIntoConstraints =  false
            myView.backgroundColor = .systemPink
            
            view.addSubview(myView)
            myView.widthAnchor.constraint(equalToConstant: 50).isActive = true
            myView.heightAnchor.constraint(equalToConstant: 50).isActive = true
            myView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
            myView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        }
        
        @IBAction @objc func changeImageFunc(_ sender: Any) {
            // just an example image
            let image = UIImage(systemName: "eraser")!
            myView.setImage(image)
        }
        
    }
    
    import UIKit
    
    class MyView: UIView {
    
        var imageView: UIImageView
        
        override init(frame: CGRect) {
         
            
            imageView = UIImageView()
            imageView.translatesAutoresizingMaskIntoConstraints = false
            super.init(frame: frame)
            
            addSubview(imageView)
            imageView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true
            imageView.heightAnchor.constraint(equalTo: self.heightAnchor).isActive = true
            imageView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
            imageView.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
    
        }
        
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        func setImage(_ image: UIImage) {
             // Set the image for the internal UIImageView
             imageView.image = image
         }
    
    }
    

    Which results in:

    ImageView example