0

I have a standard UIView added via IB which changes size based on orientation using constraints. Programatically I add a custom component (sub-classing UIView) to this view which by default is the sam size as its parent view. Problem is, how do I get my custom view (programatically added) to update its size based to match its parent when the parents size changes (due to orientation change)?

@IBOutlet weak var cardView: UIView!
override func viewDidLoad() {
    super.viewDidLoad()

    let frame = cardView.bounds
    // Custom component sub classes UI View
    // Should always be same size as its parent
    let imageTemplateView: ImageTemplateView = ImageTemplateView(frame: frame)

    cardView.addSubview(imageTemplateView)
}
kb920
  • 3,039
  • 2
  • 33
  • 44
MikeJ
  • 2,367
  • 3
  • 18
  • 23

4 Answers4

1

Set your programmatically added view's top,bottom,leading and trailing constraints with constant 0 of each. So, it will always keep same size with respect to parent view that you have added in IB. If you want rational(like half height and width of parent view or anything else) height or width then you can manage it by playing with constant and multiplier.

If you don't have idea that how to add constraints programmatically then you can refer This SO post.

Community
  • 1
  • 1
Ketan Parmar
  • 27,092
  • 9
  • 50
  • 75
  • I think using viewDidLayoutSubviews is simplest in this instance, but I can see how setting the constraints programatically is beneficial for greater positioning accuracy - Many Thanks – MikeJ Aug 23 '16 at 07:06
  • 1
    you're welcome..!!! adding new objects in `viewDidLayoutSubviews` is not good approach. You should add it from `viewdidload` which is get called only once. – Ketan Parmar Aug 23 '16 at 07:11
1

Here comes viewDidLayoutSubviewsto resolve our issue,

Description:

When the bounds change for a view controller's view, the view adjusts the positions of its subviews and then the system calls this method.

Instead of viewDidLoad use viewDidLayoutSubviewsas follows

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    let imageTemplateView: ImageTemplateView = ImageTemplateView(frame: frame)
    cardView.addSubview(imageTemplateView)
    imageTemplateView.clipsToBounds = true
}

UPDATE:

  • Declare variable above viewdidload

    var imageTemplateView: ImageTemplateView = ImageTemplateView()
    
  • set frame and add it as sub view in viewdidload

    override func viewDidLoad() {
      imageTemplateView = ImageTemplateView(frame: frame)
      cardView.addSubview(imageTemplateView)
      imageTemplateView.clipsToBounds = true
    }
    
  • In viewDidLayoutSubviews just set the frame alone,so that whenever orientation changes ImageTemplateView's frame will be updated

    override func viewDidLayoutSubviews() {
      super.viewDidLayoutSubviews()
      imageTemplateView = ImageTemplateView(frame: frame)
    }
    
Gokul G
  • 2,046
  • 15
  • 22
  • it will keep adds one more imageTemplateView as subview when ever viewDidLayoutSubviews called – Ravi Aug 23 '16 at 06:23
  • This is wrong approach. adding any object like imageview or label or else in `viewDidLayoutSubviews` is bad idea because everytime it will add new object when `viewDidLayoutSubviews` get called. If your device's orientation change then also this method will be called. So add view in `viewdidload` and resize it in `viewDidLayoutSubviews` according to need. – Ketan Parmar Aug 23 '16 at 07:10
  • raki already suggested this.check update..Only changing the frame in `viewDidLayoutSubviews` – Gokul G Aug 23 '16 at 07:15
1

try this

@IBOutlet weak var cardView: UIView!
var imageTemplateView:ImageTemplateView!

override func viewDidLoad() 
{
    super.viewDidLoad()
    imageTemplateView = ImageTemplateView(frame: cardView.bounds)
    cardView.addSubview(imageTemplateView)
}

override func viewDidLayoutSubviews() 
{
    super.viewDidLayoutSubviews()
    imageTemplateView.frame = cardView.bounds
}
Ravi
  • 2,441
  • 1
  • 11
  • 30
0

You can use Size Class feature. Set constraint and add view base or orientation change. Check this Tutorial http://www.hossamghareeb.com/size-classes-tutorial/

kb920
  • 3,039
  • 2
  • 33
  • 44
  • I'm using Size Classes on the UIView added via IB to alter its appearance based on orientation/device. Not sure how I would do that programatically on the custom view thats added - All this view needs to do is be the same size as its parent – MikeJ Aug 23 '16 at 05:38