Просмотр исходного кода

Refactor FLEXHierarchyTableViewCell

- All view properties private
- Adjust padding between subviews
- Color indicator view now shows actual color and transparency
Tanner Bennett лет назад: 6
Родитель
Сommit
3647c8deee

+ 2 - 2
Classes/ViewHierarchy/TreeExplorer/FLEXHierarchyTableViewCell.h

@@ -13,7 +13,7 @@
 - (id)initWithReuseIdentifier:(NSString *)reuseIdentifier;
 
 @property (nonatomic) NSInteger viewDepth;
-@property (nonatomic) UIColor *viewColor;
-@property (nonatomic) UIView *viewBackgroundColorView;
+@property (nonatomic) UIColor *randomColorTag;
+@property (nonatomic) UIColor *indicatedViewColor;
 
 @end

+ 82 - 41
Classes/ViewHierarchy/TreeExplorer/FLEXHierarchyTableViewCell.m

@@ -8,48 +8,63 @@
 
 #import "FLEXHierarchyTableViewCell.h"
 #import "FLEXUtility.h"
+#import "FLEXResources.h"
+#import "FLEXColor.h"
 
 @interface FLEXHierarchyTableViewCell ()
 
+/// Indicates how deep the view is in the hierarchy
 @property (nonatomic) UIView *depthIndicatorView;
+/// Holds the color that visually distinguishes views from one another
 @property (nonatomic) UIImageView *colorCircleImageView;
+/// A checker-patterned view, used to help show the color of a view, like a photoshop canvas
+@property (nonatomic) UIView *backgroundColorCheckerPatternView;
+/// The subview of the checker pattern view which holds the actual color of the view
+@property (nonatomic) UIView *viewBackgroundColorView;
 
 @end
 
 @implementation FLEXHierarchyTableViewCell
 
-- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier
-{
+- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier {
     return [self initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier];
 }
 
-- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
-{
+- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
     self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
     if (self) {
         self.depthIndicatorView = [UIView new];
         self.depthIndicatorView.backgroundColor = [FLEXUtility hierarchyIndentPatternColor];
         [self.contentView addSubview:self.depthIndicatorView];
         
-        UIImage *defaultCircleImage = [FLEXUtility circularImageWithColor:UIColor.blackColor radius:5.0];
+        UIImage *defaultCircleImage = [FLEXUtility circularImageWithColor:UIColor.blackColor radius:5];
         self.colorCircleImageView = [[UIImageView alloc] initWithImage:defaultCircleImage];
         [self.contentView addSubview:self.colorCircleImageView];
         
-        self.textLabel.font = [UIFont fontWithName:@"HelveticaNeue-Medium" size:14.0];
+        self.textLabel.font = UIFont.flex_defaultTableCellFont;
         self.detailTextLabel.font = UIFont.flex_defaultTableCellFont;
         self.accessoryType = UITableViewCellAccessoryDetailButton;
         
+        // Use a pattern-based color to simplify application of the checker pattern
+        static UIColor *checkerPatternColor = nil;
+        static dispatch_once_t once;
+        dispatch_once(&once, ^{
+            checkerPatternColor = [UIColor colorWithPatternImage:FLEXResources.checkerPattern];
+        });
+        
+        self.backgroundColorCheckerPatternView = [UIView new];
+        self.backgroundColorCheckerPatternView.clipsToBounds = YES;
+        self.backgroundColorCheckerPatternView.layer.borderColor = FLEXColor.tertiaryBackgroundColor.CGColor;
+        self.backgroundColorCheckerPatternView.layer.borderWidth = 2.f / UIScreen.mainScreen.scale;
+        self.backgroundColorCheckerPatternView.backgroundColor = checkerPatternColor;
+        [self.contentView addSubview:self.backgroundColorCheckerPatternView];
         self.viewBackgroundColorView = [UIView new];
-        self.viewBackgroundColorView.clipsToBounds = YES;
-        self.viewBackgroundColorView.layer.borderColor = UIColor.blackColor.CGColor;
-        self.viewBackgroundColorView.layer.borderWidth = 1.0f;
-        [self.contentView addSubview:self.viewBackgroundColorView];
+        [self.backgroundColorCheckerPatternView addSubview:self.viewBackgroundColorView];
     }
     return self;
 }
 
-- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
-{
+- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
     UIColor *originalColour = self.viewBackgroundColorView.backgroundColor;
     [super setHighlighted:highlighted animated:animated];
     
@@ -60,8 +75,7 @@
     self.viewBackgroundColorView.backgroundColor = originalColour;
 }
 
-- (void)setSelected:(BOOL)selected animated:(BOOL)animated
-{
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
     UIColor *originalColour = self.viewBackgroundColorView.backgroundColor;
     [super setSelected:selected animated:animated];
     
@@ -71,58 +85,85 @@
     self.viewBackgroundColorView.backgroundColor = originalColour;
 }
 
-- (void)layoutSubviews
-{
+- (void)layoutSubviews {
     [super layoutSubviews];
     
-    const CGFloat kContentPadding = 10.0;
-    const CGFloat kDepthIndicatorWidthMultiplier = 4.0;
-    const CGFloat kViewBackgroundColourDimension = 20;
+    const CGFloat kContentPadding = 6;
+    const CGFloat kDepthIndicatorWidthMultiplier = 4;
+    const CGFloat kViewColorIndicatorSize = 22;
+    
+    const CGRect bounds = self.contentView.bounds;
+    const CGFloat centerY = CGRectGetMidY(bounds);
+    const CGFloat textLabelCenterY = CGRectGetMidY(self.textLabel.frame);
     
-    CGRect depthIndicatorFrame = CGRectMake(kContentPadding, 0, self.viewDepth * kDepthIndicatorWidthMultiplier, self.contentView.bounds.size.height);
-    self.depthIndicatorView.frame = depthIndicatorFrame;
+    BOOL hideCheckerView = self.backgroundColorCheckerPatternView.hidden;
+    CGFloat maxWidth = CGRectGetMaxX(bounds);
+    maxWidth -= (hideCheckerView ? kContentPadding : (kViewColorIndicatorSize + kContentPadding * 2));
     
+    CGRect depthIndicatorFrame = self.depthIndicatorView.frame = CGRectMake(
+        kContentPadding, 0, self.viewDepth * kDepthIndicatorWidthMultiplier, CGRectGetHeight(bounds)
+    );
+    
+    // Circle goes after depth, and its center Y = textLabel's center Y
     CGRect circleFrame = self.colorCircleImageView.frame;
-    circleFrame.origin.x = CGRectGetMaxX(depthIndicatorFrame);
-    circleFrame.origin.y = self.textLabel.frame.origin.y + FLEXFloor((self.textLabel.frame.size.height - circleFrame.size.height) / 2.0);
+    circleFrame.origin.x = CGRectGetMaxX(depthIndicatorFrame) + kContentPadding;
+    circleFrame.origin.y = FLEXFloor(textLabelCenterY - CGRectGetHeight(circleFrame) / 2.f);
     self.colorCircleImageView.frame = circleFrame;
     
+    // Text label goes after random color circle, width extends to the edge
+    // of the contentView or to the padding before the color indicator view
     CGRect textLabelFrame = self.textLabel.frame;
-    CGFloat textOriginX = CGRectGetMaxX(circleFrame) + 4.0;
+    CGFloat textOriginX = CGRectGetMaxX(circleFrame) + kContentPadding;
     textLabelFrame.origin.x = textOriginX;
-    textLabelFrame.size.width = CGRectGetMaxX(self.contentView.frame) - kContentPadding - textOriginX - kViewBackgroundColourDimension;
+    textLabelFrame.size.width = maxWidth - textOriginX;
     self.textLabel.frame = textLabelFrame;
     
+    // detailTextLabel leading edge lines up with the circle, and the
+    // width extends to the same max X as the same max X as the textLabel
     CGRect detailTextLabelFrame = self.detailTextLabel.frame;
-    CGFloat detailOriginX = CGRectGetMaxX(depthIndicatorFrame);
+    CGFloat detailOriginX = circleFrame.origin.x;
     detailTextLabelFrame.origin.x = detailOriginX;
-    detailTextLabelFrame.size.width = CGRectGetMaxX(self.contentView.bounds) - kContentPadding - detailOriginX;
+    detailTextLabelFrame.size.width = maxWidth - detailOriginX;
     self.detailTextLabel.frame = detailTextLabelFrame;
     
-    CGRect viewBackgroundColourViewFrame = self.textLabel.frame;
-    viewBackgroundColourViewFrame.size.width = kViewBackgroundColourDimension;
-    viewBackgroundColourViewFrame.size.height = kViewBackgroundColourDimension;
-    viewBackgroundColourViewFrame.origin.x = CGRectGetMaxX(self.textLabel.frame) + kContentPadding;
-    viewBackgroundColourViewFrame.origin.y = ABS(CGRectGetHeight(self.contentView.frame) -  CGRectGetHeight(viewBackgroundColourViewFrame)) / 2;
+    // Checker pattern view starts after the padding after the max X of textLabel,
+    // and is centered vertically within the entire contentView
+    self.backgroundColorCheckerPatternView.frame = CGRectMake(
+        CGRectGetMaxX(self.textLabel.frame) + kContentPadding,
+        centerY - kViewColorIndicatorSize / 2.f,
+        kViewColorIndicatorSize,
+        kViewColorIndicatorSize
+    );
     
-    self.viewBackgroundColorView.frame = viewBackgroundColourViewFrame;
-    self.viewBackgroundColorView.layer.cornerRadius = kViewBackgroundColourDimension / 2;
+    // Background color view fills it's superview
+    self.viewBackgroundColorView.frame = self.backgroundColorCheckerPatternView.bounds;
+    self.backgroundColorCheckerPatternView.layer.cornerRadius = kViewColorIndicatorSize / 2.f;
 }
 
-- (void)setViewColor:(UIColor *)viewColor
-{
-    if (![_viewColor isEqual:viewColor]) {
-        _viewColor = viewColor;
-        self.colorCircleImageView.image = [FLEXUtility circularImageWithColor:viewColor radius:6.0];
+- (void)setRandomColorTag:(UIColor *)randomColorTag {
+    if (![_randomColorTag isEqual:randomColorTag]) {
+        _randomColorTag = randomColorTag;
+        self.colorCircleImageView.image = [FLEXUtility circularImageWithColor:randomColorTag radius:6];
     }
 }
 
-- (void)setViewDepth:(NSInteger)viewDepth
-{
+- (void)setViewDepth:(NSInteger)viewDepth {
     if (_viewDepth != viewDepth) {
         _viewDepth = viewDepth;
         [self setNeedsLayout];
     }
 }
 
+- (UIColor *)indicatedViewColor {
+    return self.viewBackgroundColorView.backgroundColor;
+}
+
+- (void)setIndicatedViewColor:(UIColor *)color {
+    self.viewBackgroundColorView.backgroundColor = color;
+    
+    // Hide the checker pattern view if there is no background color
+    self.backgroundColorCheckerPatternView.hidden = color == nil;
+    [self setNeedsLayout];
+}
+
 @end

+ 2 - 15
Classes/ViewHierarchy/TreeExplorer/FLEXHierarchyTableViewController.m

@@ -213,8 +213,9 @@ typedef NS_ENUM(NSUInteger, FLEXHierarchyScope) {
 
     cell.textLabel.text = [FLEXUtility descriptionForView:view includingFrame:NO];
     cell.detailTextLabel.text = [FLEXUtility detailDescriptionForView:view];
-    cell.viewColor = [FLEXUtility consistentRandomColorForObject:view];
+    cell.randomColorTag = [FLEXUtility consistentRandomColorForObject:view];
     cell.viewDepth = self.depthsForViews[view].integerValue;
+    cell.indicatedViewColor = view.backgroundColor;
 
     if (view.isHidden || view.alpha < 0.01) {
         cell.textLabel.textColor = FLEXColor.deemphasizedTextColor;
@@ -224,20 +225,6 @@ typedef NS_ENUM(NSUInteger, FLEXHierarchyScope) {
         cell.detailTextLabel.textColor = FLEXColor.primaryTextColor;
     }
     
-    // Use a pattern-based color to simplify application of the checker pattern.
-    static UIColor *checkerPatternColor = nil;
-    static dispatch_once_t once;
-    dispatch_once(&once, ^{
-        checkerPatternColor = [UIColor colorWithPatternImage:FLEXResources.checkerPattern];
-    });
-    
-    UIColor *viewColor = view.backgroundColor;
-    if (!viewColor || [viewColor isEqual:UIColor.clearColor]) {
-        cell.viewBackgroundColorView.backgroundColor = checkerPatternColor;
-    } else {
-        cell.viewBackgroundColorView.backgroundColor = viewColor;
-    }
-    
     return cell;
 }