2016-11-14 8 views
0

Отладка автоматической компоновки в iOS может быть довольно неприятной. Мы ищем способ сбрасывать subviews и их ограничения таким образом, чтобы обеспечить лучшую отладку.iOS: Дерево демпинга иерархии представлений и ограничений

Есть два полезных способов использовать отладчик, чтобы получить некоторую информацию:

  • сбросами дерево просмотров: po [[UIWindow keyWindow] recursiveDescription]
  • Трассировка ограничения: po [[UIWindow keyWindow] _autolayoutTrace];

Есть несколько ответов на StackOverflow с идеи для сброса просмотров , но без соответствующих ограничений. Есть ли полезный способ сделать это?

ответ

0

Следующая функция может быть использована для хорошего дампа дерева для обоих взглядов и их соответствующие авто-макета ограничения:

void dumpViewRecursivelyWithConstraints(UIView *vw, NSString *title) 
{ 
    if (!vw) { 
     vw = [[[[UIApplication sharedApplication] keyWindow] subviews] lastObject]; 
    } 
    void (^dumpViewRecursively)(UIView*, NSString*, NSMutableString*); //local var definition 
    void (^ __block __weak weakDumpViewRecursively)(UIView*, NSString*, NSMutableString*); //weak copy for recursion 
    weakDumpViewRecursively = dumpViewRecursively = ^void(UIView *vw, NSString* gap, NSMutableString *mStr) { 
     [mStr appendFormat:@"%@.%@\n", gap, vw]; 
     for (NSLayoutConstraint *c in vw.constraints) { 
      NSString *cStr = [NSString stringWithFormat:@"%@", c]; 
      NSInteger space = [cStr rangeOfString:@" "].location; //skipping up to space for a neater output 
      [mStr appendFormat:@"%@| %@\n", gap, [cStr substringFromIndex:space+1]]; 
     } 
     [mStr appendFormat:@"%@`----------------------------\n", gap]; 
     NSString *nextGap = [gap stringByAppendingString:@"  "]; 
     NSArray *subs = [vw subviews]; 
     for (int i=0; i<[subs count]; i++) { 
      weakDumpViewRecursively(subs[i], nextGap, mStr); //call myself recursively 
     } 
    }; 
    NSMutableString *mStr = [[NSMutableString alloc] init]; 
    [mStr appendFormat:@"\n\n************** %@: **************\n", title]; 
    dumpViewRecursively(vw, @"", mStr); 
    NSLog(@"%@", mStr); 
} 

Результат выглядит следующим образом:

.<UIView: 0x12c5bcb10; frame = (0 45; 1024 703); autoresize = W+H; gestureRecognizers = <NSArray: 0x12e436c70>; layer = <CALayer: 0x12c5b8580>> 
| UIScrollView:0x12d176a00.width == UIView:0x12c5bcb10.width> 
| UIScrollView:0x12d176a00.height == UIView:0x12c5bcb10.height> 
| UIScrollView:0x12d176a00.centerX == UIView:0x12c5bcb10.centerX> 
| UIScrollView:0x12d176a00.centerY == UIView:0x12c5bcb10.centerY> 
| PlayerView:0x12c5bda20.width == UIView:0x12c5bcb10.width> 
`---------------------------- 
    .<UIScrollView: 0x12d176a00; frame = (0 0; 1024 703); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x12e18b6e0>; layer = <CALayer: 0x12e054ec0>; contentOffset: {0, 0}; contentSize: {1848, 703}> 
    | V:|-(0)-[UIView:0x12c5d1860] (Names: '|':UIScrollView:0x12d176a00)> 
    | H:|-(0)-[UIView:0x12c5d1860](LTR) (Names: '|':UIScrollView:0x12d176a00)> 
    | UIView:0x12c5d1860.height == UIScrollView:0x12d176a00.height> 
    `---------------------------- 
      .<UIView: 0x12c5d1860; frame = (0 0; 1848 703); layer = <CALayer: 0x12c5ad540>> 
      | H:[UIView:0x12c5d1860(1848)]> 
      | H:|-(0)-[PlayerView:0x12c5bda20](LTR) (Names: '|':UIView:0x12c5d1860)> 
      | V:|-(0)-[PlayerView:0x12c5bda20] (Names: '|':UIView:0x12c5d1860)> 
      | PlayerView:0x12c5bda20.height == UIView:0x12c5d1860.height> 
      | UIView:0x12e02bf50.top == UIView:0x12c5d1860.centerY - 10>