浏览代码

1.封装iOS布局约束。

Pen Li 7 年之前
父节点
当前提交
ff5ffb4bd3
共有 2 个文件被更改,包括 699 次插入0 次删除
  1. 87 0
      common/LayoutConstraint/UIView+RAConstraint.h
  2. 612 0
      common/LayoutConstraint/UIView+RAConstraint.m

+ 87 - 0
common/LayoutConstraint/UIView+RAConstraint.h

@@ -0,0 +1,87 @@
+//
+//  UIView+JKConstraint.h
+//  Constraint
+//
+//  Created by Jack on 2018/12/10.
+//  Copyright © 2018年 Jack Template. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface RAConstraint : NSObject
+
+@property (nonatomic,readonly,copy) RAConstraint *(^ra_offset)(CGFloat offset);
+@property (nonatomic,readonly,copy) RAConstraint *(^ra_lessThanOrEqualTo)(RAConstraint *constraint);
+@property (nonatomic,readonly,copy) RAConstraint *(^ra_equalTo)(RAConstraint *constraint);
+@property (nonatomic,readonly,copy) RAConstraint *(^ra_greaterThanOrEqualTo)(RAConstraint *constraint);
+@property (nonatomic,readonly,copy) RAConstraint *(^ra_priority)(UILayoutPriority priority);
+
+@property (nonatomic,readonly,copy) RAConstraint *(^ra_append)(NSString *identifier);
+@property (nonatomic,copy) RAConstraint *(^ra_size_greaterThanOrEqualTo)(CGFloat size);
+@property (nonatomic,copy) RAConstraint *(^ra_size_lessThanOrEqualTo)(CGFloat size);
+
+@end
+
+#pragma mark - Maker
+
+@interface RAConstraintMaker : NSObject
+
+@property (nonatomic,strong,readonly) RAConstraint *left;
+@property (nonatomic,strong,readonly) RAConstraint *top;
+@property (nonatomic,strong,readonly) RAConstraint *right;
+@property (nonatomic,strong,readonly) RAConstraint *bottom;
+@property (nonatomic,strong,readonly) RAConstraint *centerX;
+@property (nonatomic,strong,readonly) RAConstraint *centerY;
+@property (nonatomic,strong,readonly) RAConstraint *baseLine;
+@property (nonatomic,strong,readonly) RAConstraint *width;
+@property (nonatomic,strong,readonly) RAConstraint *height;
+
+@property (nonatomic,strong,readonly) RAConstraint *ra_safeAreaLeft API_AVAILABLE(ios(11.0),tvos(11.0));
+@property (nonatomic,strong,readonly) RAConstraint *ra_safeAreaTop API_AVAILABLE(ios(11.0),tvos(11.0));
+@property (nonatomic,strong,readonly) RAConstraint *ra_safeAreaRight API_AVAILABLE(ios(11.0),tvos(11.0));
+@property (nonatomic,strong,readonly) RAConstraint *ra_safeAreaBottom API_AVAILABLE(ios(11.0),tvos(11.0));
+
+@end
+
+#pragma mark - UIView
+
+@interface UIView (RAConstraint)
+
+@property (nonatomic,strong,readonly) RAConstraint *left;
+@property (nonatomic,strong,readonly) RAConstraint *top;
+@property (nonatomic,strong,readonly) RAConstraint *right;
+@property (nonatomic,strong,readonly) RAConstraint *bottom;
+@property (nonatomic,strong,readonly) RAConstraint *centerX;
+@property (nonatomic,strong,readonly) RAConstraint *centerY;
+@property (nonatomic,strong,readonly) RAConstraint *baseLine;
+@property (nonatomic,strong,readonly) RAConstraint *width;
+@property (nonatomic,strong,readonly) RAConstraint *height;
+
+@property (nonatomic,strong,readonly) RAConstraint *ra_safeAreaLeft API_AVAILABLE(ios(11.0),tvos(11.0));
+@property (nonatomic,strong,readonly) RAConstraint *ra_safeAreaTop API_AVAILABLE(ios(11.0),tvos(11.0));
+@property (nonatomic,strong,readonly) RAConstraint *ra_safeAreaRight API_AVAILABLE(ios(11.0),tvos(11.0));
+@property (nonatomic,strong,readonly) RAConstraint *ra_safeAreaBottom API_AVAILABLE(ios(11.0),tvos(11.0));
+
+- (void)ra_applyConstraints:(void(^)(RAConstraintMaker *maker))apply;
+
+/**
+ * it will remove all of its constraints before installing them again.
+ */
+- (void)ra_remakeConstraints:(void(^)(RAConstraintMaker *maker))remake;
+
+@end
+
+
+#pragma mark - View Controller
+
+@interface UIViewController (RAConstraint)
+
+@property (nonatomic,strong,readonly) RAConstraint *ra_topLayoutGuid;
+@property (nonatomic,strong,readonly) RAConstraint *ra_topLayoutGuidTop;
+@property (nonatomic,strong,readonly) RAConstraint *ra_topLayoutGuidBottom;
+
+@property (nonatomic,strong,readonly) RAConstraint *ra_bottomLayoutGuid;
+@property (nonatomic,strong,readonly) RAConstraint *ra_bottomLayoutGuidTop;
+@property (nonatomic,strong,readonly) RAConstraint *ra_bottomLayoutGuidBottom;
+
+@end

+ 612 - 0
common/LayoutConstraint/UIView+RAConstraint.m

@@ -0,0 +1,612 @@
+//
+//  UIView+RAConstraint.m
+//  Constraint
+//
+//  Created by Jack on 2018/12/10.
+//  Copyright © 2018年 Jack Template. All rights reserved.
+//
+
+#import "UIView+RAConstraint.h"
+#import <objc/runtime.h>
+
+#pragma mark - Constraint
+
+@interface RAConstraint ()
+
+@property (nonatomic,weak) id appliedView;
+@property (nonatomic,weak) NSLayoutConstraint *constraint;
+@property (nonatomic,assign) UILayoutPriority priority;
+@property (nonatomic,assign) BOOL validate;
+@property (nonatomic,copy) NSString *identifier;
+
+@property (nonatomic,assign) NSLayoutAttribute attribute;
+@property (nonatomic,assign) NSLayoutRelation relation;
+@property (nonatomic,weak) UIView *toView;
+@property (nonatomic,assign) NSLayoutAttribute toAttribute;
+@property (nonatomic,assign) CGFloat constant;
+
+@property (nonatomic,copy) RAConstraint *(^ra_p_offset)(CGFloat offset);
+@property (nonatomic,copy) RAConstraint *(^ra_p_lessThanOrEqualTo)(RAConstraint *constraint);
+@property (nonatomic,copy) RAConstraint *(^ra_p_equalTo)(RAConstraint *constraint);
+@property (nonatomic,copy) RAConstraint *(^ra_p_greaterThanOrEqualTo)(RAConstraint *constraint);
+@property (nonatomic,copy) RAConstraint *(^ra_p_priority)(UILayoutPriority prioruty);
+
+@property (nonatomic,strong) NSMutableDictionary<NSString *,RAConstraint *> *appendConstraints;
+@property (nonatomic,copy) RAConstraint *(^ra_p_append)(NSString *identifier);
+@property (nonatomic,copy) RAConstraint *(^ra_p_size_greaterThanOrEqualTo)(CGFloat size);
+@property (nonatomic,copy) RAConstraint *(^ra_p_size_lessThanOrEqualTo)(CGFloat size);
+
+@end
+
+@implementation RAConstraint
+
+- (instancetype)init {
+    if (self = [super init]) {
+        
+        _attribute = NSLayoutAttributeNotAnAttribute;
+        _relation = NSLayoutRelationEqual;
+        _toAttribute = NSLayoutAttributeNotAnAttribute;
+        _priority = UILayoutPriorityDefaultHigh;
+        
+        __weak typeof(self) weakSelf = self;
+        self.ra_p_offset = [^RAConstraint *(CGFloat offset) {
+            
+            weakSelf.validate = YES;
+            weakSelf.constant = offset;
+            return weakSelf;
+        } copy];
+        
+        self.ra_p_lessThanOrEqualTo = [^RAConstraint *(RAConstraint *constraint) {
+            
+            weakSelf.validate = YES;
+            weakSelf.toView = constraint.appliedView;
+            weakSelf.relation = NSLayoutRelationLessThanOrEqual;
+            weakSelf.toAttribute = constraint.attribute;
+            
+            return weakSelf;
+        } copy];
+        
+        self.ra_p_equalTo = [^RAConstraint *(RAConstraint *constraint) {
+            
+            weakSelf.validate = YES;
+            weakSelf.toView = constraint.appliedView;
+            weakSelf.relation = NSLayoutRelationEqual;
+            weakSelf.toAttribute = constraint.attribute;
+            
+            return weakSelf;
+        } copy];
+        
+        self.ra_p_greaterThanOrEqualTo = [^RAConstraint *(RAConstraint *constraint) {
+            
+            weakSelf.validate = YES;
+            weakSelf.toView = constraint.appliedView;
+            weakSelf.relation = NSLayoutRelationGreaterThanOrEqual;
+            weakSelf.toAttribute = constraint.attribute;
+            
+            return weakSelf;
+        } copy];
+        
+        self.ra_p_priority = [^RAConstraint *(UILayoutPriority priority) {
+           
+            weakSelf.priority = priority;
+            
+            return weakSelf;
+        } copy];
+        
+        self.ra_p_append = [^RAConstraint *(NSString *identifier) {
+            
+            if (!identifier) {
+                return nil;
+            }
+            
+            if (weakSelf.appendConstraints[identifier]) {
+                return weakSelf.appendConstraints[identifier];
+            }
+            
+            RAConstraint *constraint = [RAConstraint new];
+            constraint.appliedView = weakSelf.appliedView;
+            constraint.attribute = weakSelf.attribute;
+            
+            weakSelf.appendConstraints[identifier] = constraint;
+            
+            return constraint;
+            
+        } copy];
+        
+        self.ra_p_size_lessThanOrEqualTo = [^RAConstraint *(CGFloat size) {
+            
+            if (weakSelf.attribute != NSLayoutAttributeWidth && weakSelf.attribute != NSLayoutAttributeHeight) {
+                return weakSelf;
+            }
+            
+            weakSelf.validate = YES;
+            weakSelf.toView = nil;
+            weakSelf.relation = NSLayoutRelationLessThanOrEqual;
+            weakSelf.toAttribute = NSLayoutAttributeNotAnAttribute;
+            weakSelf.ra_offset(size);
+            
+            return weakSelf;
+        } copy];
+        
+        self.ra_p_size_greaterThanOrEqualTo = [^RAConstraint *(CGFloat size) {
+            
+            if (weakSelf.attribute != NSLayoutAttributeWidth && weakSelf.attribute != NSLayoutAttributeHeight) {
+                return weakSelf;
+            }
+            
+            weakSelf.validate = YES;
+            weakSelf.toView = nil;
+            weakSelf.relation = NSLayoutRelationGreaterThanOrEqual;
+            weakSelf.toAttribute = NSLayoutAttributeNotAnAttribute;
+            weakSelf.ra_offset(size);
+            
+            return weakSelf;
+        } copy];
+    }
+    return self;
+}
+
+- (RAConstraint *(^)(CGFloat))ra_offset {
+    return self.ra_p_offset;
+}
+
+- (RAConstraint *(^)(RAConstraint *))ra_lessThanOrEqualTo {
+    return self.ra_p_lessThanOrEqualTo;
+}
+
+- (RAConstraint *(^)(RAConstraint *))ra_equalTo {
+    return self.ra_p_equalTo;
+}
+
+- (RAConstraint *(^)(RAConstraint *))ra_greaterThanOrEqualTo {
+    return self.ra_p_greaterThanOrEqualTo;
+}
+
+- (RAConstraint *(^)(UILayoutPriority))ra_priority {
+    return self.ra_p_priority;
+}
+
+- (RAConstraint *(^)(NSString *))ra_append {
+    return self.ra_p_append;
+}
+
+- (RAConstraint *(^)(CGFloat))ra_size_lessThanOrEqualTo {
+    return self.ra_p_size_lessThanOrEqualTo;
+}
+
+- (RAConstraint *(^)(CGFloat))ra_size_greaterThanOrEqualTo {
+    return self.ra_p_size_greaterThanOrEqualTo;
+}
+
+- (void)jk_uninstall {
+    
+    if (self.appliedView && self.appliedViewIsView && self.validate && self.constraint) {
+        
+        UIView *appliedView = ((UIView *)self.appliedView);
+        if ((self.attribute == NSLayoutAttributeWidth || self.attribute == NSLayoutAttributeHeight) && !self.toView) {
+            
+            [appliedView removeConstraint:self.constraint];
+        } else {
+            
+            [appliedView.superview removeConstraint:self.constraint];
+        }
+    }
+    
+    [self.appendConstraints enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, RAConstraint * _Nonnull obj, BOOL * _Nonnull stop) {
+       
+        [obj jk_uninstall];
+    }];
+    
+    self.validate = NO;
+    self.constraint = nil;
+    
+    self.toView = nil;
+    self.relation = NSLayoutRelationEqual;
+    self.toAttribute = NSLayoutAttributeNotAnAttribute;
+    self.constant = 0;
+    self.priority = UILayoutPriorityDefaultHigh;
+    
+    [self.appendConstraints removeAllObjects];
+}
+
+- (void)jk_install {
+    
+    if (self.appliedView && self.appliedViewIsView && self.validate && !self.constraint) {
+        
+        UIView *appliedView = ((UIView *)self.appliedView);
+        NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:appliedView
+                                                                      attribute:self.attribute
+                                                                      relatedBy:self.relation
+                                                                         toItem:self.toView
+                                                                      attribute:self.toAttribute
+                                                                     multiplier:1
+                                                                       constant:self.constant];
+        self.constraint = constraint;
+        self.constraint.priority = self.priority;
+        
+        if ((self.attribute == NSLayoutAttributeWidth || self.attribute == NSLayoutAttributeHeight) && !self.toView) {
+            [appliedView addConstraint:self.constraint];
+        } else{
+            [appliedView.superview addConstraint:self.constraint];
+        }
+    }
+    
+    [self.appendConstraints enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, RAConstraint * _Nonnull obj, BOOL * _Nonnull stop) {
+        
+        [obj jk_install];
+    }];
+}
+
+- (NSMutableDictionary *)appendConstraints {
+    if (!_appendConstraints) {
+        _appendConstraints = [NSMutableDictionary dictionary];
+    }
+    return _appendConstraints;
+}
+
+- (BOOL)appliedViewIsView {
+    BOOL isView = [self.appliedView isKindOfClass:[UIView class]];
+    return isView;
+}
+
+@end
+
+#pragma mark - Maker
+
+@interface RAConstraintMaker ()
+
+@property (nonatomic,weak) UIView *appliedView;
+
+@property (nonatomic,strong) RAConstraint *left;
+@property (nonatomic,strong) RAConstraint *top;
+@property (nonatomic,strong) RAConstraint *right;
+@property (nonatomic,strong) RAConstraint *bottom;
+@property (nonatomic,strong) RAConstraint *centerX;
+@property (nonatomic,strong) RAConstraint *centerY;
+@property (nonatomic,strong) RAConstraint *baseLine;
+@property (nonatomic,strong) RAConstraint *width;
+@property (nonatomic,strong) RAConstraint *height;
+
+@property (nonatomic,strong) RAConstraint *ra_safeAreaLeft API_AVAILABLE(ios(11.0),tvos(11.0));
+@property (nonatomic,strong) RAConstraint *ra_safeAreaTop API_AVAILABLE(ios(11.0),tvos(11.0));
+@property (nonatomic,strong) RAConstraint *ra_safeAreaRight API_AVAILABLE(ios(11.0),tvos(11.0));
+@property (nonatomic,strong) RAConstraint *ra_safeAreaBottom API_AVAILABLE(ios(11.0),tvos(11.0));
+
+@property (nonatomic,strong) NSMutableArray<RAConstraint *> *constraints;
+
+@end
+
+@implementation RAConstraintMaker
+
+- (instancetype)initWithAppliedView:(UIView *)view {
+    if (self = [super init]) {
+        self.appliedView = view;
+        [self.constraints addObjectsFromArray:@[
+                                                self.left,
+                                                self.top,
+                                                self.right,
+                                                self.bottom,
+                                                self.centerX,
+                                                self.centerY,
+                                                self.baseLine,
+                                                self.width,
+                                                self.height
+                                                ]];
+    }
+    return self;
+}
+
+- (NSMutableArray<RAConstraint *> *)constraints {
+    if (!_constraints) {
+        _constraints = [NSMutableArray array];
+    }
+    return _constraints;
+}
+
+- (RAConstraint *)left {
+    if (!_left) {
+        _left = [RAConstraint new];
+        _left.attribute = NSLayoutAttributeLeft;
+        _left.appliedView = self.appliedView;
+    }
+    return _left;
+}
+
+- (RAConstraint *)top {
+    if (!_top) {
+        _top = [RAConstraint new];
+        _top.attribute = NSLayoutAttributeTop;
+        _top.appliedView = self.appliedView;
+    }
+    return _top;
+}
+
+- (RAConstraint *)right {
+    if (!_right) {
+        _right = [RAConstraint new];
+        _right.attribute = NSLayoutAttributeRight;
+        _right.appliedView = self.appliedView;
+    }
+    return _right;
+}
+
+- (RAConstraint *)bottom {
+    if (!_bottom) {
+        _bottom = [RAConstraint new];
+        _bottom.attribute = NSLayoutAttributeBottom;
+        _bottom.appliedView = self.appliedView;
+    }
+    return _bottom;
+}
+
+- (RAConstraint *)centerX {
+    if (!_centerX) {
+        _centerX = [RAConstraint new];
+        _centerX.attribute = NSLayoutAttributeCenterX;
+        _centerX.appliedView = self.appliedView;
+    }
+    return _centerX;
+}
+
+- (RAConstraint *)centerY {
+    if (!_centerY) {
+        _centerY = [RAConstraint new];
+        _centerY.attribute = NSLayoutAttributeCenterY;
+        _centerY.appliedView = self.appliedView;
+    }
+    return _centerY;
+}
+
+- (RAConstraint *)baseLine {
+    if (!_baseLine) {
+        _baseLine = [RAConstraint new];
+        _baseLine.attribute = NSLayoutAttributeBaseline;
+        _baseLine.appliedView = self.appliedView;
+    }
+    return _baseLine;
+}
+
+- (RAConstraint *)width {
+    if (!_width) {
+        _width = [RAConstraint new];
+        _width.attribute = NSLayoutAttributeWidth;
+        _width.appliedView = self.appliedView;
+    }
+    return _width;
+}
+
+- (RAConstraint *)height {
+    if (!_height) {
+        _height = [RAConstraint new];
+        _height.attribute = NSLayoutAttributeHeight;
+        _height.appliedView = self.appliedView;
+    }
+    return _height;
+}
+
+// safe area
+
+- (RAConstraint *)ra_safeAreaLeft {
+    if (!_ra_safeAreaLeft) {
+        _ra_safeAreaLeft = [RAConstraint new];
+        _ra_safeAreaLeft.attribute = NSLayoutAttributeLeft;
+        _ra_safeAreaLeft.appliedView = self.appliedView.safeAreaLayoutGuide;
+    }
+    return _ra_safeAreaLeft;
+}
+
+- (RAConstraint *)ra_safeAreaTop {
+    if (!_ra_safeAreaTop) {
+        _ra_safeAreaTop = [RAConstraint new];
+        _ra_safeAreaTop.attribute = NSLayoutAttributeTop;
+        _ra_safeAreaTop.appliedView = self.appliedView.safeAreaLayoutGuide;
+    }
+    return _ra_safeAreaTop;
+}
+
+- (RAConstraint *)ra_safeAreaRight {
+    if (!_ra_safeAreaRight) {
+        _ra_safeAreaRight = [RAConstraint new];
+        _ra_safeAreaRight.attribute = NSLayoutAttributeRight;
+        _ra_safeAreaRight.appliedView = self.appliedView.safeAreaLayoutGuide;
+    }
+    return _ra_safeAreaRight;
+}
+
+- (RAConstraint *)ra_safeAreaBottom {
+    if (!_ra_safeAreaBottom) {
+        _ra_safeAreaBottom = [RAConstraint new];
+        _ra_safeAreaBottom.attribute = NSLayoutAttributeBottom;
+        _ra_safeAreaBottom.appliedView = self.appliedView.safeAreaLayoutGuide;
+    }
+    return _ra_safeAreaBottom;
+}
+
+- (void)jk_install {
+    if (self.appliedView) {
+        
+        for (RAConstraint *constraint in self.constraints) {
+            [constraint jk_install];
+        }
+    }
+}
+
+- (void)jk_uninstall {
+    
+    if (self.appliedView) {
+        
+        for (RAConstraint *constraint in self.constraints) {
+            [constraint jk_uninstall];
+        }
+    }
+}
+
+@end
+
+#pragma mark - UIView
+
+static const char RAMaker = '\a';
+
+@implementation UIView (RAConstraint)
+
+- (void)setRA_Maker:(RAConstraintMaker *)maker {
+    
+    if (maker) {
+        objc_setAssociatedObject(self, &RAMaker, maker, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+    }
+}
+
+- (RAConstraintMaker *)ra_maker {
+    RAConstraintMaker *maker = objc_getAssociatedObject(self, &RAMaker);
+    if (maker == nil) {
+        maker = [[RAConstraintMaker alloc] initWithAppliedView:self];
+        [self setRA_Maker:maker];
+    }
+    return maker;
+}
+
+- (void)ra_applyConstraints:(void(^)(RAConstraintMaker *maker))apply {
+    if (self.superview) {
+        self.superview.translatesAutoresizingMaskIntoConstraints = NO;
+        self.translatesAutoresizingMaskIntoConstraints = NO;
+        
+        RAConstraintMaker *maker = [self ra_maker];
+        if (apply) {
+            apply(maker);
+        }
+        
+        [self applyMaker:maker];
+    }
+}
+
+- (void)applyMaker:(RAConstraintMaker *)maker {
+    
+    if (maker) {
+        [self setRA_Maker:maker];
+        [maker jk_install];
+        
+        [self.superview layoutIfNeeded];
+    }
+}
+
+- (void)ra_remakeConstraints:(void(^)(RAConstraintMaker *maker))remake {
+    
+    [[self ra_maker] jk_uninstall];
+    
+    [self ra_applyConstraints:remake];
+}
+
+#pragma mark - P
+
+- (RAConstraint *)left {
+    return [self ra_maker].left;
+}
+
+- (RAConstraint *)top {
+    return [self ra_maker].top;
+}
+
+- (RAConstraint *)right {
+    return [self ra_maker].right;
+}
+
+- (RAConstraint *)bottom {
+    return [self ra_maker].bottom;
+}
+
+- (RAConstraint *)centerX {
+    return [self ra_maker].centerX;
+}
+
+- (RAConstraint *)centerY {
+    return [self ra_maker].centerY;
+}
+
+- (RAConstraint *)baseLine {
+    return [self ra_maker].baseLine;
+}
+
+- (RAConstraint *)width {
+    return [self ra_maker].width;
+}
+
+- (RAConstraint *)height {
+    return [self ra_maker].height;
+}
+
+// safe area
+
+- (RAConstraint *)ra_safeAreaLeft {
+    return [self ra_maker].ra_safeAreaLeft;
+}
+
+- (RAConstraint *)ra_safeAreaTop {
+    return [self ra_maker].ra_safeAreaTop;
+}
+
+- (RAConstraint *)ra_safeAreaRight {
+    return [self ra_maker].ra_safeAreaRight;
+}
+
+- (RAConstraint *)ra_safeAreaBottom {
+    return [self ra_maker].ra_safeAreaBottom;
+}
+
+@end
+
+#pragma mark - View Controller
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+@implementation UIViewController (RAConstraint)
+
+- (RAConstraint *)ra_topLayoutGuid {
+    
+    RAConstraint *constraint = [RAConstraint new];
+    constraint.attribute = NSLayoutAttributeBottom;
+    constraint.appliedView = self.topLayoutGuide;
+    return constraint;
+}
+
+- (RAConstraint *)ra_topLayoutGuidTop {
+    
+    RAConstraint *constraint = [RAConstraint new];
+    constraint.attribute = NSLayoutAttributeTop;
+    constraint.appliedView = self.topLayoutGuide;
+    return constraint;
+}
+
+- (RAConstraint *)ra_topLayoutGuidBottom {
+    
+    RAConstraint *constraint = [RAConstraint new];
+    constraint.attribute = NSLayoutAttributeBottom;
+    constraint.appliedView = self.topLayoutGuide;
+    return constraint;
+}
+
+- (RAConstraint *)ra_bottomLayoutGuid {
+    
+    RAConstraint *constraint = [RAConstraint new];
+    constraint.attribute = NSLayoutAttributeTop;
+    constraint.appliedView = self.bottomLayoutGuide;
+    return constraint;
+}
+
+- (RAConstraint *)ra_bottomLayoutGuidTop {
+    RAConstraint *constraint = [RAConstraint new];
+    constraint.attribute = NSLayoutAttributeTop;
+    constraint.appliedView = self.bottomLayoutGuide;
+    return constraint;
+}
+
+- (RAConstraint *)ra_bottomLayoutGuidBottom {
+    RAConstraint *constraint = [RAConstraint new];
+    constraint.attribute = NSLayoutAttributeBottom;
+    constraint.appliedView = self.bottomLayoutGuide;
+    return constraint;
+}
+
+#pragma clang diagnostic pop
+
+@end