15

So i am using a custom function to format an subview that I am adding to a UICollectionViewCell. It is from Brian Voong's public project here: https://github.com/purelyswift/facebook_feed_dynamic_cell_content/blob/master/facebookfeed2/ViewController.swift.

func addConstraintsWithFormat(format: String, views: UIView...) {
   var viewsDictionary = [String: UIView]()
   for (index, view) in views.enumerate() {
      let key = "v\(index)"
      viewsDictionary[key] = view
      view.translatesAutoresizingMaskIntoConstraints = false
   }
   addConstraints(NSLayoutConstraint.constraintsWithVisualFormat(format, options: NSLayoutFormatOptions(), metrics: nil, views: viewsDictionary))
}

What is interesting, is that in my UICollectionView I add a SubView to a single cell, and set the background color to white. The background is white when I comment out the line which sets the background for the subview, and no background color is set when I uncomment out the line setting the visually formatted constraints for the subview.

Here are the two lines which clobber each other:

func chronicleOneClicked(sender: UIButton) {
   point1view.backgroundColor = UIColor.whiteColor()

   addSubview(point1view)
   //When the below is commented the background of point1view disappears   
   //addConstraintsWithFormat("|-50-[v0]-50-|", views: point1view)
}

when I do print(subviews) i see that the UIView with the white background color is the highest in the view stack (top of the stack). When i print out subviews[subviews.count-1].backgroundColor I get the Optional(UIDeviceWhiteColorSpace 1 1) which is what I expect. it is strange because the color is not displayed.

I am not sure how to go about seeing what is happening behind the scenes to confirm that the background is being set at all in the latter case.

This all happens in a class for the UiCollectionViewCell which I am using as the class of one of my UICollectionView Cells which can be viewed in its entirety here:

https://gist.github.com/ebbnormal/edb79a15dab4797946e0d1f6905c2dd0

Here is a screen shot from both cases, the first case is where the line addConstraintsWithFormat is commented out, and the second case is where it is uncommented: The subview of point1subview is highlighted with a white background in the first case.

enter image description here

enter image description here

This is how I setup the views. It all happens in a class that overrides UICollectionViewCell

class myClass : UICollectionViewCell {
   var chronicle: BrowsableChronicle? {
      didSet{
         //etc.
         point1.addTarget(self, action: #selector(chronicleOneClicked(_:)), forControlEvents: UIControlEvents.TouchUpInside)
      }
   }

   override init(frame: CGRect) {
      super.init(frame: frame)
      setupViews()
   }

   let point1 : PointButtonView = {
      let pointView = PointButtonView(frame: CGRectMake(0, 0, 25, 25 ))
      return pointView
   }()
   //NOTE here is where I create the view, whose background doesn't display
   let point1view : UIView = {
      let pointView = UIView(frame: CGRectMake( 0, 0, 200,  270))
      pointView.backgroundColor = UIColor.whiteColor()
      let title = UILabel(frame: CGRectMake(0, 0, 200, 21))
      title.font = UIFont(name:"HelveticaNeue-Bold", size: 16.0)

      pointView.addSubview(title)
      let summary = UILabel(frame: CGRectMake(0, 0, 190, 260))
      summary.lineBreakMode = NSLineBreakMode.ByWordWrapping
      summary.numberOfLines = 4
      summary.font = UIFont(name:"HelveticaNeue", size: 12.5)
      pointView.addSubview(summary)

      let button = UIButton(frame: CGRectMake(0, 200, 190, 30))
      button.backgroundColor = UIColor(red:0.00, green:0.90, blue:0.93, alpha:1.0)
      pointView.addSubview(button)

      pointView.tag = 100

      return pointView
   }()

   //NOTE: here is where I add the subview to the UICollectionViewCell view
   func chronicleOneClicked(sender: UIButton){
      addSubview(point1view)
      addConstraintsWithFormat("H:|-20-[v0]-20-|", views: point1view)
      //TODO anytime i add a constraint here the background color leaves!
      print(subviews[subviews.count-1].backgroundColor) //Prints white
   }
}

UPDATE: I thought maybe it was related to this issue :

UITableViewCell subview disappears when cell is selected

Where the UICollectionViewCell is selected, and therefore iOS automatically sets the backgroundColor to clear. The problem is, that I implemented this class extension of UIView to see when didSet is called on the backgroundColor and when it is set to clear, i set it to white. However, it only calls didSet on the backgroundColor once, when i first set the color of the view. Here is the code I used to override the UIView class:

class NeverClearView: UIView {
   override var backgroundColor: UIColor? {
      didSet {
         print("background color is being set")
         if backgroundColor == UIColor.clearColor() {
            print("set to a clear color")
            backgroundColor = UIColor.whiteColor()
         }
      }
   }
}
juanjo
  • 3,737
  • 3
  • 39
  • 44
Thalatta
  • 4,510
  • 10
  • 48
  • 79
  • What is background? – ldindu Jul 25 '16 at 22:18
  • the `backgroundColor` is the background color of the subview, `point1view` which I am adding as a subview to my `UiCollectionViewCell` – Thalatta Jul 25 '16 at 22:19
  • And what do you mean by it disappears? – ldindu Jul 25 '16 at 22:19
  • sorry, that is confusing language that i used. i mean that the `whiteColor()` which i assign to this particular subview does not appear (Rather than dissapears) when I add the constraint. It is never there in the first place in that case :) – Thalatta Jul 25 '16 at 22:23
  • 2
    Then obviously there is something wrong with your constraints. – ldindu Jul 25 '16 at 22:24
  • is that true? I quick glance at the Visual Format of apple, shows that I am simply centering the subview relative to its superviews horizontally with a margin of 50 on each side of the view. The constraints successfully apply, the subview is placed according to the constraints, yet the color is gone. – Thalatta Jul 25 '16 at 22:26
  • Yes, it applies 50 points margin on leading and trailing edges on horizontal axis. – ldindu Jul 25 '16 at 22:27
  • nice! so yeah that works when i uncomment the constraint. but the background no longer is white. – Thalatta Jul 25 '16 at 22:28
  • What colour is it now? – ldindu Jul 25 '16 at 22:29
  • the color is now transparent. – Thalatta Jul 25 '16 at 22:29
  • How sure are you of that constraint is correct applied to point1View? – ldindu Jul 25 '16 at 22:39
  • please refer to the newly added photos. they show that the constraint is applied correctly but the background no longer is white. – Thalatta Jul 25 '16 at 22:59
  • What subviews does the White view have? At runtime what is the view frame when it disappears? – Wain Jul 28 '16 at 06:44
  • @Wain what do you mean by the view frame. you mean the entire `UICollectionViewCell` stack? The subviews that the white view are the following: `[>, >, >` – Thalatta Jul 28 '16 at 17:50
  • or do you mean `view.frame` of the subview that is supposed to have a white background? – Thalatta Jul 28 '16 at 17:56
  • the `frame` of the view when it its background dissapears is `(0.0, 0.0, 200.0, 270.0)`. it still has the same dimensions as when the white background is present, however, the background is clear. – Thalatta Jul 28 '16 at 17:58

1 Answers1

8

The difference you are seeing is obviously caused by a view frame resulting in zero width or zero height.

Let's explain how the drawing system works.

Every view has a layer that draws its background color in its bounds, which are specified by the view frame. Then every subview is drawn. However, the subviews are not limited by the frame unless you set UIView.clipsToBounds to true.

What you are seeing means the a container view has a zero frame (either width or height) but its subviews have correct frame, therefore they are displayed correctly.

There are multiple reasons why this could happen, for example:

  1. You are setting translatesAutoresizingMaskIntoConstraints to false to some system view (e.g. the content view of the UICollectionView).
  2. You have a constraint conflict, resulting in some important constraint to be removed (you should see a warning).
  3. You are missing some constraints. Specifically, I don't see you setting vertical constraints.

You should be able to debug the problem using the view debugger in Xcode. Just open your app, click the view debugger button and print the recursive description of the cell. You should see a frame that is zero.

Sulthan
  • 128,090
  • 22
  • 218
  • 270