2016-11-14 100 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>