0

I have a prototype cell with a custom class that I want to draw a few extra layers on the cell once when the cell is first initialized and not every time the cell is reused. In the past I would have done this by implementing awakeFromNib. I want to be able to access the frame of the views in my cell so I can use their dimensions in my new layer drawings, but with iOS6 the subviews all have frame width/height of 0 in the awakeFromNib method. I suspect it has to do with the new constraints layout stuff which I don't really understand yet.

- (void)awakeFromNib {
    [super awakeFromNib];
    // We only want to draw this dotted line once
    CGPoint start = CGPointZero;
    CGPoint end = CGPointMake(self.horizontalSeparator.frame.size.width, 0);
    // Category that creates a layer with a dotted line and adds it to the view.
    [self.horizontalSeparator addDottedLine:start to:end];
}

In awakeFromNib the horizontalSeparator.frame = (0 100; 0 0). How can I draw this dotted line layer once per cell and use the width of the existing horizontalSeparator view to determine the length of the line?

UPDATE

I figured out that I can use the constraints on the superview to figure out the dimensions on the subviews, but I'm still hoping someone can point me towards a better solution that doesn't make assumptions about the constraint configuration.

for (NSLayoutConstraint *constraint in self.constraints) {
    if (// Find a constraint for the horizontalSeparator
        (constraint.firstItem == self.horizontalSeparator
         || constraint.secondItem == self.horizontalSeparator)
        && // Make sure it affects the leading or trailing edge.
        (constraint.firstAttribute == NSLayoutAttributeLeading
         || constraint.firstAttribute == NSLayoutAttributeTrailing)) {
               CGFloat margin = constraint.constant;
               CGPoint start = CGPointZero;
               CGPoint end = CGPointMake(self.frame.size.width - (2 * margin), 0);
               [self.horizontalSeparator addDottedLine:start to:end];
               _isInitialized = YES;
               break;
    }
}
Ted Tomlinson
  • 773
  • 2
  • 7
  • 18
  • I have a temp hack to make this work by setting an _isInitialized flag on the cell instance the first time I lay it out so I only draw the layers once, but I'm wondering if there is a better way. – Ted Tomlinson Jan 28 '13 at 22:46
  • It might help to see what is happening in addDottedLine. Are you adding a CALAyer as a sublayer of horizontalSeparator's layer? CALayers in iOS do not support layout managers, so if your intention is to make sure the CALayer is the same width (minus margin) as the view that contains it, you will probably need to do some subclassing and override layoutSubviews: More about this problem here: http://stackoverflow.com/questions/2504151/calayers-didnt-get-resized-on-its-uiviews-bounds-change-why – Peter E Jan 29 '13 at 14:39
  • yeah - that's exactly what I'm doing. My intention was to let designers resize/layout the view in IB, then do custom drawing (like the dotted line) based on the size of the views they create. The views don't resize after they are drawn once so I was hoping there would be some callback at the View or UITableViewCell layer (ie not UIViewControllers viewWillAppear) that gets called after all the subviews have been laid out via constraints. I'll just create a full dottedLineView that manages layout dynamically via layoutSubviews. – Ted Tomlinson Jan 29 '13 at 23:49

0 Answers0