1
votes

I have a "main view" that I am trying to load multiple custom views into...

Inside this "main view", I have "template views" that I want to move custom views into and out of (ex. one "template view" could have a custom view with a search field in it at one point in the apps lifecycle and at another point it could contain an image view). I want to do this to avoid having many ViewControllers and Segues in my app.

I plan on doing this by giving the "main view" multiple instance properties that are of the type of the difference custom views AND multiple template views which will hold different custom views depending on the app lifecycle.

Inside the "main view" ViewDidLoad() I initialize the custom view properties by calling the CustomView.init(frame:) function and I pass into the function the bounds of the "template view" I want the CustomView to be sized to.

// EDIT: I actually initialize the custom view properties from within a custom cell's awakeFromNib function. The cell is loaded into a Table View that is a subview of the Main View. //

This seems to work... except that the width of the Custom View is incorrect when the app runs. The Custom View's trailing end extends past the width of the Template View (all the way to the very edge of the screen), but the Template View correctly terminates 10 points before the trailing edge of the screen.

Inside the CustomView class file, the init function looks like this:



class CustomView: UIView {

     var firstViewInHierarchy: UIView

     var possibleFrame: CGRect? = nil

     override init(frame: CGRect) {
          super.init(frame: frame)
          self.possibleFrame = frame
          commonInit()
     }

     required init?(coder: NSCoder) {
          super.init(coder: coder)
          commonInit()
     }

     private func commonInit() {
          Bundle.main.loadNibNamed("MainProfileView", owner: self, options: nil)

          if let theFrame = self.possibleFrame {
               self.firstViewInHierarchy.frame = theFrame
               self.firstViewInHierarchy.bounds = theFrame
               self.frame = theFrame
               self.bounds = theFrame
          }

          filmView1.layer.cornerRadius = 10
          filmView1.clipsToBounds = true

          imageContainer.layer.cornerRadius = 10
          imageContainer.clipsToBounds = true

          imageView.layer.cornerRadius = 5
          imageView.clipsToBounds = true

          self.addSubview(firstView)
     }

I set the frame and bounds of both the CustomView.frame property and the CustomView.firstViewInHierarchy property to the CGRect defined by the possibleFrame because I thought that if one was not set to the possibleFrame, that would cause the custom view to size itself incorrectly once initialized via the init(frame:) call... which I call in the "Main View"'s Table View's custom cell class awakeFromNib function... here:

class CustomCellThatGoesIntoMainView: UITableViewCell {

     @IBOutlet weak var templateViewOne: UIView!

     @IBOutlet weak var templateViewTwo: UIView!

     var customView1: CustomViewTypeOne?

     var customView2: CustomViewTypeTwo?

    // the template views are actually inside a table view cell inside a tableview which is 
    // inside the main view

     override func awakeFromNib() {
          super.awakeFromNib()

          self.customView1 = CustomViewType1(frame: templateViewOne.bounds)
          self.templateViewOne.addSubview(profileView!)

          self.customView2 = CustomViewType2(frame: templateViewTwo.bounds)
          self.templateViewOne.addSubview(profileView!)


     }
}


I resized one of the template views to have a much greater Height and the Custom View did size itself appropriately height-wise. However, it still extends to the very edge of the screen. 

???
1

1 Answers

0
votes

It turns out that when I printed the frame and bounds of all the objects involved:

  • The UIScreen.main.bounds.width was equal to 375
  • The TemplateView.bounds.width was equal to 394
  • The CustomView.width after initialization was equal to 394

  • The CGRect of the TemplateView frame was [10, 120, 394, 155], which, asides for the width, was correct. I set the height to 155 in the storyboard.

However... there seemed to be issues in the XIB file that handled the CustomView. I have already moved passed this problem, but I think the CustomView's hierarchy was something like:

  • FirstViewInHierarchy |--- FirstSubview |--- ImageContainer...etc.

I believe that the FirstViewInHierarchy had no constraints, as it was set to free form.

The FirstSubview had constraints that I thought set it equal to the FirstViewInHierarchy, but I think they were complicated... possibly by the ImageContainer constraints. I really blew past this so I am sorry for not knowing exactly.

Anyways... I decided to delete these files and start again with the same approach posed in the question.

This time, in the XIB file, I simply got rid of the FirstSubview and set the ImageView to be equal to the FirstViewInTheHierarchy.

Then, in Interface Builder, instead of setting the TemplateViews trailing and leading constraints equal to trailing and leading edges of the screen +/- ten points, I gave the template view 4 constraints:

  1. A leading constraint = 10 points
  2. A top constraint = 10 points
  3. A width constraint = (UIScreen.main.bounds.width * 0.5)
  4. A height constraint = (UIScreen.main.bounds.width * 0.5)

Inside the MainView's table view's custom cell's file, where the custom view gets initialized with a frame, I instead initialized the custom view with a frame NOT EQUAL TO THE FRAME OR BOUNDS OF THE TEMPLATE VIEW, but with a CGRect of [origin 0, 0] and width and height of [widthConstraint.constant, heightConstraint.constant].

I set the constant values of the constraints right before calling the CustomView.init(frame:) function, and the views were placed correctly.