Search code examples
swiftxcodeuikitautolayoutuistackview

insertSubview() is working on one UIView in UIStackView, But not on adjacent view


I am working on autolayouts in storyboard, I have two adjacent UIViews in a single UIStackView. I need to insert image in both UIView background.

Problem is that background image is showing in left UIView but not in right UIView. Below is the code.

extension UIView {
    
    func backgroundImage(image: String){
        let background = UIImage(named: image)
        
        var imageView : UIImageView!
        imageView = UIImageView(frame: self.frame)
        print(self.frame.origin.x)
        imageView.contentMode =  UIView.ContentMode.scaleAspectFill
        imageView.clipsToBounds = true
        imageView.image = background
        imageView.center = self.center
        self.insertSubview(imageView, at: 0)
    }
}

private func loadViews() {
        leftCardView.backgroundImage(image: "green-card")
        rightCardView.backgroundImage(image: "purple-card")
    }

and loadViews() is called in viewDidAppear().

Below are the images. enter image description here

enter image description here

You can see that, in the View Inspector, right UIView (Purple View) background is absent. I have searched a lot, but didn't come to any fix.


Solution

  • The problem is with this line: imageView.center = self.center. You are setting the imageView's center (in UIView coordinates) to the UIView's center (in UIStackView coordinates). Do what @HangarRash suggested: set imageView's frame to self.bounds, and don't set the center.

    let imageView = UIImageView(frame: self.bounds)
    imageView.center = self.center <- remove this
    

    Or, set the center like this:

    imageView.center = CGPoint(x: self.bounds.width / 2, y: self.bounds.height / 2)
    

    Here's a diagram to explain. Since leftCardView and rightCardView are subviews of UIStackView, their center's are relative to the stack view's origin. In my example, center (x, y) = (64, 64) and (232, 64) for left and right card views. Since the imageViews are subviews of the UIViews, their centers are relative to the UIView's origins. The left imageView is ok, but the right imageView was placed off-screen in your original code.

    enter image description here

    For the fix, self.bounds.width / 2 = 64, and self.bounds.height / 2 = 64, for both card views, placing the imageViews in the center of their UIViews.