2016-11-14 30 views
0

在iOS中調試自動佈局可能會很煩人。我們正在尋找一種方法來轉儲子視圖和它們的約束,以便更好地進行調試。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>