Why viewDidLayout is only called once on iOS 7, but several times on iOS 8

I have a project using autolayout,

And I notice that after a viewWillAppearcouple viewWillLayoutSubViewsthey viewDidLayoutSubViewswill be called several times on iOS 8, for my case it is usually 2-3 times.

The fist viewDidLayoutSubViewswill get the wrong frame size, so I need to avoid the first viewDidLayoutSubViewsone and then turn on my views again.

However, when I tested it on iOS 7, I found that only one pair was called viewWillLayoutSubViewsand viewDidLayoutSubViewstherefore my code broke again.

My question is: what has changed on iOS 8 for this behavior?

EDIT: I inserted the demo code here:

In the code, _pieChart will be added to self.ChartViewCanvas and self.ChartViewCanvas will use autostart. _pieChart is the old project code that is drawn without an automatic layout.

I needed to draw a pie chart in front of viewDidAppear, because drawing in viewDidAppear would have a 1 second delay compared to other views in the storyboard. This is not allowed for me.

Is there any way to know when the last one viewDidLayoutSubViews? A call [self.ChartViewCanvas addSubview:_pieChart];several times will lead to poor performance, and sometimes _pieChart drawInRect will not be called every time, so the chart does not update.

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    _pieChart.delegate = self;
        if (!_pieChart) {
            _pieChart = [[PieChartView alloc] initWithFrame:CGRectMake(0, 0, pieRadius * 2, pieRadius * 2)];
        }else {
            [_pieChart setFrame:CGRectMake(0, 0, pieRadius * 2, pieRadius * 2)];
        }

    //_pieChart.translatesAutoresizingMaskIntoConstraints = NO;
    if ([_pieChart superview]) {
        [_pieChart removeFromSuperview];
    }
    [self.ChartViewCanvas addSubview:_pieChart];
}
+4
source share
2 answers

, Apple , , . iOS8 Apple (), VC , UITraitCollections.
, UIAlertView , , , VC.
, , , , , , .
  dispatch_once, , .
, , - .
[]
, DidLoad:

- (void)viewDidLoad
{
    [super viewDidLoad];
    //.. your stuff

    //We don't need any frame autolayout wil take care of calculating it on its pass
    _pieChart = [[PieChartView alloc]initWithFrame:CGRectZero];
    _pieChart.delegate = self;
    _pieChart.translatesAutoresizingMaskIntoConstraints = NO;
    [self.ChartViewCanvas addSubview:_pieChart];
    NSDictionary *bindings = NSDictionaryOfVariableBindings(_pieChart);
    // We create constraints to tell the view that it needs to sctretch its bounds to the superview
    NSString *formatTemplate = @"%@:|[_pieChart]|";
    for (NSString * axis in @[@"H",@"V"]) {
        NSString * format = [NSString stringWithFormat:formatTemplate,axis];
        NSArray * constraints = [NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:nil views:bindings];
        [_pieChart.superview addConstraints:constraints];
    }

    // Do any additional setup after loading the view.
}

, drawRect:, draw rect , , .

0

, : 1 iOS7 3 iOS8. , , viewWillAppear , viewDidAppear, iOS7.

, viewDidLoad ( viewWillAppear), . - :

- (void)viewDidLoad{
  [super viewDidLoad];

  _pieChart = [[PieChartView alloc] initWithFrame:CGRectMake(0, 0, pieRadius * 2, pieRadius * 2)];
  [self.ChartViewCanvas addSubview:_pieChart];
  _pieChart.delegate = self;
}

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];

    [_pieChart setFrame:CGRectMake(0, 0, pieRadius * 2, pieRadius * 2)];
}

iOS7 8 :

iOS7

i) viewWillAppear.

ii) subviews. , , .

ii) viewDidAppear.

iOS8

i) viewWillAppear.

ii) subviews. , , .

iii) . , - .

iv) viewDidAppear.

v) subviews. , -, , .

0

All Articles