text: //
  //  UIView+SUIAdditions.m
  //  SUIUtilsDemo
  //
  //  Created by RandomSuio on 16/2/16.
  //  Copyright © 2016年 RandomSuio. All rights reserved.
  //
  
  #import "UIView+SUIAdditions.h"
  #import "SUIMacro.h"
  #import "NSObject+SUIAdditions.h"
  
  @implementation UIView (SUIAdditions)
  
  
  /*o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o*
   *  Frame
   *o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~*/
  
  #pragma mark - Frame
  
  - (CGFloat)sui_x
  {
      return self.frame.origin.x;
  }
  - (void)setSui_x:(CGFloat)sui_x
  {
      CGRect curRect = self.frame;
      if (curRect.origin.x != sui_x) {
          curRect.origin.x = sui_x;
          self.frame = curRect;
      }
  }
  
  - (CGFloat)sui_y
  {
      return self.frame.origin.y;
  }
  - (void)setSui_y:(CGFloat)sui_y
  {
      CGRect curRect = self.frame;
      if (curRect.origin.y != sui_y) {
          curRect.origin.y = sui_y;
          self.frame = curRect;
      }
  }
  
  - (CGFloat)sui_width
  {
      return self.frame.size.width;
  }
  - (void)setSui_width:(CGFloat)sui_width
  {
      CGRect curRect = self.frame;
      if (curRect.size.width != sui_width) {
          curRect.size.width = sui_width;
          self.frame = curRect;
      }
  }
  
  - (CGFloat)sui_height
  {
      return self.frame.size.height;
  }
  - (void)setSui_height:(CGFloat)sui_height
  {
      CGRect curRect = self.frame;
      if (curRect.size.height != sui_height) {
          curRect.size.height = sui_height;
          self.frame = curRect;
      }
  }
  
  - (CGPoint)sui_origin
  {
      return self.frame.origin;
  }
  - (void)setSui_origin:(CGPoint)sui_origin
  {
      CGRect curRect = self.frame;
      if (!CGPointEqualToPoint(curRect.origin, sui_origin)) {
          curRect.origin = sui_origin;
          self.frame = curRect;
      }
  }
  
  - (CGSize)sui_size
  {
      return self.frame.size;
  }
  - (void)setSui_size:(CGSize)sui_size
  {
      CGRect curRect = self.frame;
      if (!CGSizeEqualToSize(curRect.size, sui_size)) {
          curRect.size = sui_size;
          self.frame = curRect;
      }
  }
  
  - (CGFloat)sui_right
  {
      return CGRectGetMaxX(self.frame);
  }
  - (CGFloat)sui_bottom
  {
      return CGRectGetMaxY(self.frame);
  }
  
  - (CGFloat)sui_centerX
  {
      return CGRectGetMidX(self.frame);
  }
  - (void)setSui_centerX:(CGFloat)sui_centerX
  {
      CGPoint curCenter = self.center;
      if (curCenter.x != sui_centerX) {
          curCenter.x = sui_centerX;
          self.center = curCenter;
      }
  }
  - (CGFloat)sui_centerY
  {
      return CGRectGetMidY(self.frame);
  }
  - (void)setSui_centerY:(CGFloat)sui_centerY
  {
      CGPoint curCenter = self.center;
      if (curCenter.y != sui_centerY) {
          curCenter.y = sui_centerY;
          self.center = curCenter;
      }
  }
  
  
  /*o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o*
   *  Constraint
   *o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~*/
  
  #pragma mark - Constraint
  
  - (NSLayoutConstraint *)sui_constraintForAttribute:(NSLayoutAttribute)attribute
  {
      NSArray *constraintArray = nil;
      if (attribute == NSLayoutAttributeWidth || attribute == NSLayoutAttributeHeight) {
          constraintArray = [self constraints];
      } else {
          constraintArray = [self.superview constraints];
      }
      
      NSPredicate *predicate = [NSPredicate predicateWithFormat:@"firstAttribute = %d && (firstItem = %@ || secondItem = %@)", attribute, self, self];
      NSArray *fillteredArray = [constraintArray filteredArrayUsingPredicate:predicate];
      if (fillteredArray.count) {
          NSLayoutConstraint *curConstraint = fillteredArray.firstObject;
          return curConstraint;
      }
      return nil;
  }
  
  - (NSLayoutConstraint *)sui_constraintTop
  {
      return [self sui_constraintForAttribute:NSLayoutAttributeTop];
  }
  - (NSLayoutConstraint *)sui_constraintBottom
  {
      return [self sui_constraintForAttribute:NSLayoutAttributeBottom];
  }
  - (NSLayoutConstraint *)sui_constraintLeading
  {
      return [self sui_constraintForAttribute:NSLayoutAttributeLeft];
  }
  - (NSLayoutConstraint *)sui_constraintTrailing
  {
      return [self sui_constraintForAttribute:NSLayoutAttributeRight];
  }
  - (NSLayoutConstraint *)sui_constraintWidth
  {
      return [self sui_constraintForAttribute:NSLayoutAttributeWidth];
  }
  - (NSLayoutConstraint *)sui_constraintHeight
  {
      return [self sui_constraintForAttribute:NSLayoutAttributeHeight];
  }
  - (NSLayoutConstraint *)sui_constraintCenterX
  {
      return [self sui_constraintForAttribute:NSLayoutAttributeCenterX];
  }
  - (NSLayoutConstraint *)sui_constraintCenterY
  {
      return [self sui_constraintForAttribute:NSLayoutAttributeCenterY];
  }
  - (NSLayoutConstraint *)sui_constraintBaseline
  {
      return [self sui_constraintForAttribute:NSLayoutAttributeBaseline];
  }
  - (void)sui_layoutPinnedToSuperview
  {
      SUIAssert(self.superview, @"no superview ⤭ %@ ⤪", self);
      self.translatesAutoresizingMaskIntoConstraints = NO;
      [self.superview addConstraints:
       [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[self]-0-|"
                                               options:0
                                               metrics:nil
                                                 views:NSDictionaryOfVariableBindings(self)]];
      [self.superview addConstraints:
       [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[self]-0-|"
                                               options:0
                                               metrics:nil
                                                 views:NSDictionaryOfVariableBindings(self)]];
  }
  
  
  /*o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o*
   *  Nib
   *o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~*/
  
  #pragma mark - Nib
  
  - (BOOL)sui_loadNib
  {
      UIView *curMainView = [self sui_mainView];
      if (!curMainView) {
          [self setSui_loadNib:YES];
      }
      return YES;
  }
  - (void)setSui_loadNib:(BOOL)sui_loadNib
  {
      if (sui_loadNib) {
          UIView *curMainView = [self sui_mainView];
          if (!curMainView) {
              curMainView = [[NSBundle mainBundle] loadNibNamed:gClassName(self) owner:self options:nil][0];
              curMainView.frame = self.bounds;
              curMainView.backgroundColor = [UIColor clearColor];
              [self setSui_mainView:curMainView];
              [self addSubview:curMainView];
              [curMainView sui_layoutPinnedToSuperview];
          }
      } else {
          [self setSui_mainView:nil];
      }
  }
  
  - (instancetype)sui_mainView
  {
      return [self sui_getAssociatedObjectWithKey:@selector(sui_mainView)];
  }
  - (void)setSui_mainView:(UIView *)sui_mainView
  {
      [self sui_setAssociatedRetainObject:sui_mainView key:@selector(sui_mainView)];
  }
  
  + (instancetype)sui_loadInstanceFromNib
  {
      return [self sui_loadInstanceFromNibWithName:NSStringFromClass([self class])];
  }
  + (instancetype)sui_loadInstanceFromNibWithName:(NSString *)nibName
  {
      return [self sui_loadInstanceFromNibWithName:nibName owner:nil];
  }
  + (instancetype)sui_loadInstanceFromNibWithName:(NSString *)nibName owner:(id)owner
  {
      return [self sui_loadInstanceFromNibWithName:nibName owner:nil bundle:[NSBundle mainBundle]];
  }
  + (instancetype)sui_loadInstanceFromNibWithName:(NSString *)nibName owner:(id)owner bundle:(NSBundle *)bundle
  {
      NSArray *nibViews = [bundle loadNibNamed:nibName owner:owner options:nil];
      UIView *curMainView = nil;
      for (id curObj in nibViews) {
          if ([curObj isKindOfClass:[self class]]) {
              curMainView = curObj;
              break;
          }
      }
      return curMainView;
  }
  
  
  /*o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o*
   *  Layer
   *o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~*/
  
  #pragma mark - Layer
  
  - (CGFloat)sui_cornerRadius
  {
      return self.layer.cornerRadius;
  }
  - (void)setSui_cornerRadius:(CGFloat)sui_cornerRadius
  {
      self.layer.cornerRadius = sui_cornerRadius;
      self.layer.masksToBounds = (sui_cornerRadius > 0);
  }
  
  - (CGFloat )sui_borderWidth
  {
      return self.layer.borderWidth;
  }
  - (void)setSui_borderWidth:(CGFloat)sui_borderWidth
  {
      self.layer.borderWidth = sui_borderWidth;
  }
  
  - (UIColor *)sui_borderColor
  {
      return [UIColor colorWithCGColor:self.layer.borderColor];
  }
  - (void)setSui_borderColor:(UIColor *)sui_borderColor
  {
      self.layer.borderColor = [sui_borderColor CGColor];
  }
  
  - (UIColor *)sui_shadowColor
  {
      return [UIColor colorWithCGColor:self.layer.shadowColor];
  }
  - (void)setSui_shadowColor:(UIColor *)sui_shadowColor
  {
      self.layer.shadowColor = [sui_shadowColor CGColor];
  }
  
  - (CGFloat)sui_shadowOpacity
  {
      return self.layer.shadowOpacity;
  }
  - (void)setSui_shadowOpacity:(CGFloat)sui_shadowOpacity
  {
      self.layer.shadowOpacity = sui_shadowOpacity;
  }
  
  - (CGSize)sui_shadowOffset
  {
      return self.layer.shadowOffset;
  }
  - (void)setSui_shadowOffset:(CGSize)sui_shadowOffset
  {
      self.layer.shadowOffset = sui_shadowOffset;
  }
  
  - (CGFloat)sui_shadowRadius
  {
      return self.layer.shadowRadius;
  }
  - (void)setSui_shadowRadius:(CGFloat)sui_shadowRadius
  {
      self.layer.shadowRadius = sui_shadowRadius;
  }
  
  - (BOOL)sui_shadowPath
  {
      if (self.layer.shadowRadius) return YES;
      return NO;
  }
  - (void)setSui_shadowPath:(BOOL)sui_shadowPath
  {
      self.layer.shadowPath = [[UIBezierPath bezierPathWithRect:self.layer.bounds] CGPath];
  }
  
  
  /*o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o*
   *  Relationship
   *o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~*/
  
  #pragma mark - Relationship
  
  - (UIViewController *)sui_currentVC
  {
      Class aClass = NSClassFromString(@"UIViewController");
      for (UIView *next = [self superview]; next; next = next.superview) {
          UIResponder *nextResponder = [next nextResponder];
          if ([nextResponder isKindOfClass:aClass]) {
              return (UIViewController *)nextResponder;
          }
      }
      return nil;
  }
  
  - (UIView *)sui_findSubview:(NSString *)className
  {
      for (UIView *subView in self.subviews) {
          if ([subView isKindOfClass:NSClassFromString(className)]) {
              return subView;
          }
      }
      return nil;
  }
  - (UIView *)sui_findSupview:(NSString *)className;
  {
      for (UIView *next = [self superview]; next; next = next.superview) {
          UIView *curView = [next superview];
          if ([curView isKindOfClass:NSClassFromString(className)]) {
              return curView;
          }
      }
      return nil;
  }
  
  
  /*o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o*
   *  GestureRecognizer
   *o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~*/
  
  #pragma mark - GestureRecognizer
  
  - (void)sui_addTapGes:(void (^)(UITapGestureRecognizer *cTapGes))cb
  {
      if (!self.userInteractionEnabled) self.userInteractionEnabled = !self.userInteractionEnabled;
      UITapGestureRecognizer *curGesture = [self sui_getAssociatedObjectWithKey:_cmd];
      if (!curGesture) {
          curGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(sui_handleTapGes:)];
          [self addGestureRecognizer:curGesture];
          [self sui_setAssociatedRetainObject:curGesture key:_cmd];
      }
      [self sui_setAssociatedCopyObject:cb key:@selector(sui_handleTapGes:)];
  }
  - (void)sui_handleTapGes:(UITapGestureRecognizer *)tapGes
  {
      void (^gesBlock)(UITapGestureRecognizer *cTapGes) = [self sui_getAssociatedObjectWithKey:_cmd];
      if (gesBlock) gesBlock(tapGes);
  }
  
  - (void)sui_addLongPressGes:(void (^)(UILongPressGestureRecognizer *cLongPressGes))cb
  {
      if (!self.userInteractionEnabled) self.userInteractionEnabled = !self.userInteractionEnabled;
      UILongPressGestureRecognizer *curGesture = [self sui_getAssociatedObjectWithKey:_cmd];
      if (!curGesture) {
          curGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(sui_handleLongPressGes:)];
          [self addGestureRecognizer:curGesture];
          [self sui_setAssociatedRetainObject:curGesture key:_cmd];
      }
      [self sui_setAssociatedCopyObject:cb key:@selector(sui_handleLongPressGes:)];
  }
  - (void)sui_handleLongPressGes:(UILongPressGestureRecognizer *)longPressGes
  {
      void (^gesBlock)(UILongPressGestureRecognizer *cLongPressGes) = [self sui_getAssociatedObjectWithKey:_cmd];
      if (gesBlock) gesBlock(longPressGes);
  }
  
  
  /*o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o*
   *  Snapshot
   *o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~o~*/
  
  #pragma mark - Snapshot
  
  - (UIView *)sui_snapshotView:(BOOL)arterUpdates
  {
      return [self snapshotViewAfterScreenUpdates:arterUpdates];
  }
  - (UIImage *)sui_snapshotImage:(BOOL)arterUpdates
  {
      UIGraphicsBeginImageContextWithOptions(self.bounds.size, YES, 0.0);
      [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:arterUpdates];
      UIImage *curImage = UIGraphicsGetImageFromCurrentImageContext();
      UIGraphicsEndImageContext();
      return curImage;
  }
  - (UIImage *)sui_snapshotWithRenderInContext
  {
      UIGraphicsBeginImageContextWithOptions(self.bounds.size, YES, 0.0);
      [self.layer renderInContext:UIGraphicsGetCurrentContext()];
      UIImage *curImage = UIGraphicsGetImageFromCurrentImageContext();
      UIGraphicsEndImageContext();
      return curImage;
  }
  
  
  @end
  