0

I have build a custom view that needs to be embedded at various places.

Here is what I did along with the code:

1) Created a Swift file and an xib file called CustomLabel. Contents of CustomLabel.swift:

import UIKit

class CustomLabel: UIView {

@IBOutlet var view: UIView!
@IBOutlet weak var label: UILabel!

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    print("CustomLabel")
    Bundle.main.loadNibNamed("CustomLabel", owner: self, options: nil)


    self.addSubview(self.view)
}



}

Here is how CustomLabel.xib looks:

I have made the size

I have made the view freeform and set its height. I have added a label view inside it with constraints on all four sides.

Now I am adding this view to my Main ViewController but setting the width of this view to be bigger than the original reusable view.

This is the result:

enter image description here

The yellow background shows the extra width of the view and the black one is the original view.

How do I make sure that the reusable view is stretched to cover the whole view?

Ankit Arora
  • 110
  • 3
  • 16
  • When views are layed out prorgrammatically this is often an issue: https://stackoverflow.com/questions/47800210/when-should-translatesautoresizingmaskintoconstraints-be-set-to-true – Teetz Jan 28 '19 at 13:19
  • @Teetz setting translatesAutoresizingMaskIntoConstraints to false it making the view cover even smaller portion of the whole view. – Ankit Arora Jan 28 '19 at 13:23
  • you could also for example set it to true and give your view a flexibleWidth autoresizing mask. this should just be a hint in the right direction - not a "do this" option. – Teetz Jan 28 '19 at 13:25

1 Answers1

1

The way you are loading your XIB creates two UIView objects, where you may be thinking it creates only one.

You can easily see this using Debug View Hierarchy

Here, the Blue view is the view added to Storyboard, with constraints set normally (in this case, 40-pts from each side, height of 100, and centered vertically).

The Red view is the view you work with when designing your XIB, and it has a label with black background, constrained to 0 on all four sides.

enter image description here

Your XIB class is UIView -- so it is its own view... When you added a UIView to your storyboard and set its class to CustomLabel, that becomes the "root" view. In your code, you are adding view as a subview... which should give you the clue that you now have two UIView objects.

What's happened now is that the CustomLabel itself (which is a UIView) uses the constraints you set in storyboard, but the view subview does not have constraints set.

If you change your loading code to this (I changed your IBOutlet names, because adding "view" as a subview to another "view" can become very confusing):

class CustomLabel: UIView {

    @IBOutlet var theView: UIView!
    @IBOutlet weak var thelabel: UILabel!

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        print("CustomLabel")
        Bundle.main.loadNibNamed("CustomLabel", owner: self, options: nil)

        self.addSubview(self.theView)

        self.theView.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            self.theView.topAnchor.constraint(equalTo: self.topAnchor, constant: 0.0),
            self.theView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0.0),
            self.theView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 0.0),
            self.theView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 0.0),
            ])

    }

}

Now, your code loads the view from the XIB, adds it as a subview of CustomLabel (which, again, is a UIView itself), and sets up the constraints as you'd expect, giving this result:

enter image description here

As you can see, theView which has been added as a subview (red in this image), is now constrained to its superview - the blue CustomLabel.

DonMag
  • 69,424
  • 5
  • 50
  • 86