Discussion in 'iOS Programming' started by daproject85, Oct 12, 2012.

  1. daproject85 macrumors member

    Apr 13, 2011
    Hi Forum,

    I spent a lot of time trying understand the method - (void)layoutSubviews, and I think i have it down however there is NO WAY to step through layoutSubview and go step by step, even with break points it seems like it gets called at the very last step. I do know that somehow somewhere addSuview does invoke it. So here is my question. I have a method which creates and adds a bunch of views to other views below

    if (!(self = [super initWithFrame:CGRectZero]))
    		return nil;
        // Allow subclasses to change the view to which to add the activity view (e.g. to cover the keyboard):
        self.originalView = addToView;
        addToView = [self viewForView:addToView];
        // Configure this view (the background) and its subviews:
        [self setupBackground];
        self.labelWidth = aLabelWidth;
        self.borderView = [self makeBorderView];
        self.activityIndicator = [self makeActivityIndicator];
        self.activityLabel = [self makeActivityLabelWithText:labelText];
        // Assemble the subviews:
    	[addToView addSubview:self];
        [self addSubview:self.borderView];
        [self.borderView addSubview:self.activityIndicator];
        [self.borderView addSubview:self.activityLabel];
    	// Animate the view in, if appropriate:
    	[self animateShow];
    and here is the layouSubviews method

    - (void)layoutSubviews;
        self.frame = [self enclosingFrame];
        // If we're animating a transform, don't lay out now, as can't use the frame property when transforming:
        if (!CGAffineTransformIsIdentity(self.borderView.transform))
        CGSize textSize = [self.activityLabel.text sizeWithFont:[UIFont systemFontOfSize:[UIFont systemFontSize]]];
        // Use the fixed width if one is specified:
        if (self.labelWidth > 10)
            textSize.width = self.labelWidth;
        NSLog(@"self.activityLabel.frame is %@",NSStringFromCGRect(self.activityLabel.frame));
        self.activityLabel.frame = CGRectMake(self.activityLabel.frame.origin.x, self.activityLabel.frame.origin.y, textSize.width, textSize.height);
        // Calculate the size and position for the border view: with the indicator to the left of the label, and centered in the receiver:
    	CGRect borderFrame = CGRectZero;
        NSLog(@"self.activityIndicator.frame is %@",NSStringFromCGRect(self.activityIndicator.frame));
        borderFrame.size.width = self.activityIndicator.frame.size.width + textSize.width + 25.0;
        borderFrame.size.height = self.activityIndicator.frame.size.height + 10.0;
        borderFrame.origin.x = floor(0.5 * (self.frame.size.width - borderFrame.size.width));
        borderFrame.origin.y = floor(0.5 * (self.frame.size.height - borderFrame.size.height - 20.0));
        self.borderView.frame = borderFrame;
        // Calculate the position of the indicator: vertically centered and at the left of the border view:
        CGRect indicatorFrame = self.activityIndicator.frame;
    	indicatorFrame.origin.x = 10.0;
    	indicatorFrame.origin.y = 0.5 * (borderFrame.size.height - indicatorFrame.size.height);
        self.activityIndicator.frame = indicatorFrame;
        // Calculate the position of the label: vertically centered and at the right of the border view:
    	CGRect labelFrame = self.activityLabel.frame;
        labelFrame.origin.x = borderFrame.size.width - labelFrame.size.width - 10.0;
    	labelFrame.origin.y = floor(0.5 * (borderFrame.size.height - labelFrame.size.height));
        self.activityLabel.frame = labelFrame;
    in the first method as we can see activityLabel is added to borderView, and in the layoutSubviews method in the "calculate position of label" section we see that a call to the activityLabel frame is made. Again it is very difficult to see exactly at what point it gets called, so my question is

    1. is the layoutSubviews method smart enough to know that boarderview is activityLabels superview because of
      [self.borderView addSubview:self.activityIndicator];
    ?? because from what I see layoutSubviews gets called once...and not after every "addSubview"
  2. PhoneyDeveloper macrumors 68030


    Sep 2, 2008
    There's nothing special about layoutSubviews with regard to the debugger. You should be able to step through it the same as any other method. Do you have optimizations turned on?

    You can force a view to layout its subviews with setNeedsLayout.

    layoutSubviews is likely to be called when a view's frame changes so if the view's frame doesn't change then it may only be called one time.
  3. daproject85 thread starter macrumors member

    Apr 13, 2011
    well i know for a fact that addSubviews does call layoutSubviews also. And yes i can step through it but it does not jump into it right after a addSubviews call. I have put a breakpoint in it and it seems to jump into it at the very very end.

Share This Page