瀏覽代碼

PDFViewer(ios) - 水印的基本ui设计布局

dengkang 2 年之前
父節點
當前提交
90db34c1e2
共有 42 個文件被更改,包括 3295 次插入30 次删除
  1. 16 0
      PDFViewer/Controller/CPDFImageViewController.h
  2. 5 5
      PDFViewer/Controller/CPDFWatermarkController.m
  3. 16 0
      PDFViewer/Controller/CPDFTextViewController.h
  4. 31 0
      PDFViewer/Controller/CPDFTextViewController.m
  5. 0 16
      PDFViewer/Controller/CPDFWatermarkController.h
  6. 26 0
      PDFViewer/Masonry/MASCompositeConstraint.h
  7. 183 0
      PDFViewer/Masonry/MASCompositeConstraint.m
  8. 66 0
      PDFViewer/Masonry/MASConstraint+Private.h
  9. 268 0
      PDFViewer/Masonry/MASConstraint.h
  10. 297 0
      PDFViewer/Masonry/MASConstraint.m
  11. 138 0
      PDFViewer/Masonry/MASConstraintMaker.h
  12. 261 0
      PDFViewer/Masonry/MASConstraintMaker.m
  13. 22 0
      PDFViewer/Masonry/MASLayoutConstraint.h
  14. 13 0
      PDFViewer/Masonry/MASLayoutConstraint.m
  15. 136 0
      PDFViewer/Masonry/MASUtilities.h
  16. 49 0
      PDFViewer/Masonry/MASViewAttribute.h
  17. 46 0
      PDFViewer/Masonry/MASViewAttribute.m
  18. 48 0
      PDFViewer/Masonry/MASViewConstraint.h
  19. 406 0
      PDFViewer/Masonry/MASViewConstraint.m
  20. 29 0
      PDFViewer/Masonry/Masonry.h
  21. 72 0
      PDFViewer/Masonry/NSArray+MASAdditions.h
  22. 162 0
      PDFViewer/Masonry/NSArray+MASAdditions.m
  23. 41 0
      PDFViewer/Masonry/NSArray+MASShorthandAdditions.h
  24. 16 0
      PDFViewer/Masonry/NSLayoutConstraint+MASDebugAdditions.h
  25. 143 0
      PDFViewer/Masonry/NSLayoutConstraint+MASDebugAdditions.m
  26. 109 0
      PDFViewer/Masonry/View+MASAdditions.h
  27. 206 0
      PDFViewer/Masonry/View+MASAdditions.m
  28. 138 0
      PDFViewer/Masonry/View+MASShorthandAdditions.h
  29. 29 0
      PDFViewer/Masonry/ViewController+MASAdditions.h
  30. 42 0
      PDFViewer/Masonry/ViewController+MASAdditions.m
  31. 3 5
      PDFViewer/View/CPDFWatermarkView.h
  32. 4 4
      PDFViewer/View/CPDFWatermarkView.m
  33. 16 0
      PDFViewer/View/CPDFImageView.h
  34. 14 0
      PDFViewer/View/CPDFImageView.m
  35. 22 0
      PDFViewer/View/CPDFPageRangeDropDownList.h
  36. 13 0
      PDFViewer/View/CPDFPageRangeDropDownList.m
  37. 19 0
      PDFViewer/View/CPDFTextPreview.h
  38. 38 0
      PDFViewer/View/CPDFTextPreview.m
  39. 35 0
      PDFViewer/View/CPDFTextView.h
  40. 117 0
      PDFViewer/View/CPDFTextView.m
  41. 二進制
      PDFViewer/View/sources/btn_selected.png
  42. 0 0
      PDFViewer/View/sources/pdfImage@2x.png

+ 16 - 0
PDFViewer/Controller/CPDFImageViewController.h

@@ -0,0 +1,16 @@
+//
+//  CPDFImageViewController.h
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/19.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFImageViewController : UIViewController
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 5 - 5
PDFViewer/Controller/CPDFWatermarkController.m

@@ -1,17 +1,17 @@
 //
-//  CPDFWatermarkController.m
+//  CPDFImageViewController.m
 //  PDFViewer
 //
-//  Created by kdan on 2022/11/15.
+//  Created by kdan on 2022/11/19.
 //
 
-#import "CPDFWatermarkController.h"
+#import "CPDFImageViewController.h"
 
-@interface CPDFWatermarkController ()
+@interface CPDFImageViewController ()
 
 @end
 
-@implementation CPDFWatermarkController
+@implementation CPDFImageViewController
 
 - (void)viewDidLoad {
     [super viewDidLoad];

+ 16 - 0
PDFViewer/Controller/CPDFTextViewController.h

@@ -0,0 +1,16 @@
+//
+//  CPDFTextViewController.h
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/19.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFTextViewController : UIViewController
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 31 - 0
PDFViewer/Controller/CPDFTextViewController.m

@@ -0,0 +1,31 @@
+//
+//  CPDFTextViewController.m
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/19.
+//
+
+#import "CPDFTextViewController.h"
+
+@interface CPDFTextViewController ()
+
+@end
+
+@implementation CPDFTextViewController
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+}
+
+/*
+#pragma mark - Navigation
+
+// In a storyboard-based application, you will often want to do a little preparation before navigation
+- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
+    // Get the new view controller using [segue destinationViewController].
+    // Pass the selected object to the new view controller.
+}
+*/
+
+@end

+ 0 - 16
PDFViewer/Controller/CPDFWatermarkController.h

@@ -1,16 +0,0 @@
-//
-//  CPDFWatermarkController.h
-//  PDFViewer
-//
-//  Created by kdan on 2022/11/15.
-//
-
-#import <UIKit/UIKit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface CPDFWatermarkController : UIViewController
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 26 - 0
PDFViewer/Masonry/MASCompositeConstraint.h

@@ -0,0 +1,26 @@
+//
+//  MASCompositeConstraint.h
+//  Masonry
+//
+//  Created by Jonas Budelmann on 21/07/13.
+//  Copyright (c) 2013 cloudling. All rights reserved.
+//
+
+#import "MASConstraint.h"
+#import "MASUtilities.h"
+
+/**
+ *	A group of MASConstraint objects
+ */
+@interface MASCompositeConstraint : MASConstraint
+
+/**
+ *	Creates a composite with a predefined array of children
+ *
+ *	@param	children	child MASConstraints
+ *
+ *	@return	a composite constraint
+ */
+- (id)initWithChildren:(NSArray *)children;
+
+@end

+ 183 - 0
PDFViewer/Masonry/MASCompositeConstraint.m

@@ -0,0 +1,183 @@
+//
+//  MASCompositeConstraint.m
+//  Masonry
+//
+//  Created by Jonas Budelmann on 21/07/13.
+//  Copyright (c) 2013 cloudling. All rights reserved.
+//
+
+#import "MASCompositeConstraint.h"
+#import "MASConstraint+Private.h"
+
+@interface MASCompositeConstraint () <MASConstraintDelegate>
+
+@property (nonatomic, strong) id mas_key;
+@property (nonatomic, strong) NSMutableArray *childConstraints;
+
+@end
+
+@implementation MASCompositeConstraint
+
+- (id)initWithChildren:(NSArray *)children {
+    self = [super init];
+    if (!self) return nil;
+
+    _childConstraints = [children mutableCopy];
+    for (MASConstraint *constraint in _childConstraints) {
+        constraint.delegate = self;
+    }
+
+    return self;
+}
+
+#pragma mark - MASConstraintDelegate
+
+- (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint {
+    NSUInteger index = [self.childConstraints indexOfObject:constraint];
+    NSAssert(index != NSNotFound, @"Could not find constraint %@", constraint);
+    [self.childConstraints replaceObjectAtIndex:index withObject:replacementConstraint];
+}
+
+- (MASConstraint *)constraint:(MASConstraint __unused *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
+    id<MASConstraintDelegate> strongDelegate = self.delegate;
+    MASConstraint *newConstraint = [strongDelegate constraint:self addConstraintWithLayoutAttribute:layoutAttribute];
+    newConstraint.delegate = self;
+    [self.childConstraints addObject:newConstraint];
+    return newConstraint;
+}
+
+#pragma mark - NSLayoutConstraint multiplier proxies 
+
+- (MASConstraint * (^)(CGFloat))multipliedBy {
+    return ^id(CGFloat multiplier) {
+        for (MASConstraint *constraint in self.childConstraints) {
+            constraint.multipliedBy(multiplier);
+        }
+        return self;
+    };
+}
+
+- (MASConstraint * (^)(CGFloat))dividedBy {
+    return ^id(CGFloat divider) {
+        for (MASConstraint *constraint in self.childConstraints) {
+            constraint.dividedBy(divider);
+        }
+        return self;
+    };
+}
+
+#pragma mark - MASLayoutPriority proxy
+
+- (MASConstraint * (^)(MASLayoutPriority))priority {
+    return ^id(MASLayoutPriority priority) {
+        for (MASConstraint *constraint in self.childConstraints) {
+            constraint.priority(priority);
+        }
+        return self;
+    };
+}
+
+#pragma mark - NSLayoutRelation proxy
+
+- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation {
+    return ^id(id attr, NSLayoutRelation relation) {
+        for (MASConstraint *constraint in self.childConstraints.copy) {
+            constraint.equalToWithRelation(attr, relation);
+        }
+        return self;
+    };
+}
+
+#pragma mark - attribute chaining
+
+- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
+    [self constraint:self addConstraintWithLayoutAttribute:layoutAttribute];
+    return self;
+}
+
+#pragma mark - Animator proxy
+
+#if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV)
+
+- (MASConstraint *)animator {
+    for (MASConstraint *constraint in self.childConstraints) {
+        [constraint animator];
+    }
+    return self;
+}
+
+#endif
+
+#pragma mark - debug helpers
+
+- (MASConstraint * (^)(id))key {
+    return ^id(id key) {
+        self.mas_key = key;
+        int i = 0;
+        for (MASConstraint *constraint in self.childConstraints) {
+            constraint.key([NSString stringWithFormat:@"%@[%d]", key, i++]);
+        }
+        return self;
+    };
+}
+
+#pragma mark - NSLayoutConstraint constant setters
+
+- (void)setInsets:(MASEdgeInsets)insets {
+    for (MASConstraint *constraint in self.childConstraints) {
+        constraint.insets = insets;
+    }
+}
+
+- (void)setInset:(CGFloat)inset {
+    for (MASConstraint *constraint in self.childConstraints) {
+        constraint.inset = inset;
+    }
+}
+
+- (void)setOffset:(CGFloat)offset {
+    for (MASConstraint *constraint in self.childConstraints) {
+        constraint.offset = offset;
+    }
+}
+
+- (void)setSizeOffset:(CGSize)sizeOffset {
+    for (MASConstraint *constraint in self.childConstraints) {
+        constraint.sizeOffset = sizeOffset;
+    }
+}
+
+- (void)setCenterOffset:(CGPoint)centerOffset {
+    for (MASConstraint *constraint in self.childConstraints) {
+        constraint.centerOffset = centerOffset;
+    }
+}
+
+#pragma mark - MASConstraint
+
+- (void)activate {
+    for (MASConstraint *constraint in self.childConstraints) {
+        [constraint activate];
+    }
+}
+
+- (void)deactivate {
+    for (MASConstraint *constraint in self.childConstraints) {
+        [constraint deactivate];
+    }
+}
+
+- (void)install {
+    for (MASConstraint *constraint in self.childConstraints) {
+        constraint.updateExisting = self.updateExisting;
+        [constraint install];
+    }
+}
+
+- (void)uninstall {
+    for (MASConstraint *constraint in self.childConstraints) {
+        [constraint uninstall];
+    }
+}
+
+@end

+ 66 - 0
PDFViewer/Masonry/MASConstraint+Private.h

@@ -0,0 +1,66 @@
+//
+//  MASConstraint+Private.h
+//  Masonry
+//
+//  Created by Nick Tymchenko on 29/04/14.
+//  Copyright (c) 2014 cloudling. All rights reserved.
+//
+
+#import "MASConstraint.h"
+
+@protocol MASConstraintDelegate;
+
+
+@interface MASConstraint ()
+
+/**
+ *  Whether or not to check for an existing constraint instead of adding constraint
+ */
+@property (nonatomic, assign) BOOL updateExisting;
+
+/**
+ *	Usually MASConstraintMaker but could be a parent MASConstraint
+ */
+@property (nonatomic, weak) id<MASConstraintDelegate> delegate;
+
+/**
+ *  Based on a provided value type, is equal to calling:
+ *  NSNumber - setOffset:
+ *  NSValue with CGPoint - setPointOffset:
+ *  NSValue with CGSize - setSizeOffset:
+ *  NSValue with MASEdgeInsets - setInsets:
+ */
+- (void)setLayoutConstantWithValue:(NSValue *)value;
+
+@end
+
+
+@interface MASConstraint (Abstract)
+
+/**
+ *	Sets the constraint relation to given NSLayoutRelation
+ *  returns a block which accepts one of the following:
+ *    MASViewAttribute, UIView, NSValue, NSArray
+ *  see readme for more details.
+ */
+- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation;
+
+/**
+ *	Override to set a custom chaining behaviour
+ */
+- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute;
+
+@end
+
+
+@protocol MASConstraintDelegate <NSObject>
+
+/**
+ *	Notifies the delegate when the constraint needs to be replaced with another constraint. For example
+ *  A MASViewConstraint may turn into a MASCompositeConstraint when an array is passed to one of the equality blocks
+ */
+- (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint;
+
+- (MASConstraint *)constraint:(MASConstraint *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute;
+
+@end

+ 268 - 0
PDFViewer/Masonry/MASConstraint.h

@@ -0,0 +1,268 @@
+//
+//  MASConstraint.h
+//  Masonry
+//
+//  Created by Jonas Budelmann on 22/07/13.
+//  Copyright (c) 2013 cloudling. All rights reserved.
+//
+
+#import "MASUtilities.h"
+
+/**
+ *	Enables Constraints to be created with chainable syntax
+ *  Constraint can represent single NSLayoutConstraint (MASViewConstraint) 
+ *  or a group of NSLayoutConstraints (MASComposisteConstraint)
+ */
+@interface MASConstraint : NSObject
+
+// Chaining Support
+
+/**
+ *	Modifies the NSLayoutConstraint constant,
+ *  only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
+ *  NSLayoutAttributeTop, NSLayoutAttributeLeft, NSLayoutAttributeBottom, NSLayoutAttributeRight
+ */
+- (MASConstraint * (^)(MASEdgeInsets insets))insets;
+
+/**
+ *	Modifies the NSLayoutConstraint constant,
+ *  only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
+ *  NSLayoutAttributeTop, NSLayoutAttributeLeft, NSLayoutAttributeBottom, NSLayoutAttributeRight
+ */
+- (MASConstraint * (^)(CGFloat inset))inset;
+
+/**
+ *	Modifies the NSLayoutConstraint constant,
+ *  only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
+ *  NSLayoutAttributeWidth, NSLayoutAttributeHeight
+ */
+- (MASConstraint * (^)(CGSize offset))sizeOffset;
+
+/**
+ *	Modifies the NSLayoutConstraint constant,
+ *  only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
+ *  NSLayoutAttributeCenterX, NSLayoutAttributeCenterY
+ */
+- (MASConstraint * (^)(CGPoint offset))centerOffset;
+
+/**
+ *	Modifies the NSLayoutConstraint constant
+ */
+- (MASConstraint * (^)(CGFloat offset))offset;
+
+/**
+ *  Modifies the NSLayoutConstraint constant based on a value type
+ */
+- (MASConstraint * (^)(NSValue *value))valueOffset;
+
+/**
+ *	Sets the NSLayoutConstraint multiplier property
+ */
+- (MASConstraint * (^)(CGFloat multiplier))multipliedBy;
+
+/**
+ *	Sets the NSLayoutConstraint multiplier to 1.0/dividedBy
+ */
+- (MASConstraint * (^)(CGFloat divider))dividedBy;
+
+/**
+ *	Sets the NSLayoutConstraint priority to a float or MASLayoutPriority
+ */
+- (MASConstraint * (^)(MASLayoutPriority priority))priority;
+
+/**
+ *	Sets the NSLayoutConstraint priority to MASLayoutPriorityLow
+ */
+- (MASConstraint * (^)(void))priorityLow;
+
+/**
+ *	Sets the NSLayoutConstraint priority to MASLayoutPriorityMedium
+ */
+- (MASConstraint * (^)(void))priorityMedium;
+
+/**
+ *	Sets the NSLayoutConstraint priority to MASLayoutPriorityHigh
+ */
+- (MASConstraint * (^)(void))priorityHigh;
+
+/**
+ *	Sets the constraint relation to NSLayoutRelationEqual
+ *  returns a block which accepts one of the following:
+ *    MASViewAttribute, UIView, NSValue, NSArray
+ *  see readme for more details.
+ */
+- (MASConstraint * (^)(id attr))equalTo;
+
+/**
+ *	Sets the constraint relation to NSLayoutRelationGreaterThanOrEqual
+ *  returns a block which accepts one of the following:
+ *    MASViewAttribute, UIView, NSValue, NSArray
+ *  see readme for more details.
+ */
+- (MASConstraint * (^)(id attr))greaterThanOrEqualTo;
+
+/**
+ *	Sets the constraint relation to NSLayoutRelationLessThanOrEqual
+ *  returns a block which accepts one of the following:
+ *    MASViewAttribute, UIView, NSValue, NSArray
+ *  see readme for more details.
+ */
+- (MASConstraint * (^)(id attr))lessThanOrEqualTo;
+
+/**
+ *	Optional semantic property which has no effect but improves the readability of constraint
+ */
+- (MASConstraint *)with;
+
+/**
+ *	Optional semantic property which has no effect but improves the readability of constraint
+ */
+- (MASConstraint *)and;
+
+/**
+ *	Creates a new MASCompositeConstraint with the called attribute and reciever
+ */
+- (MASConstraint *)left;
+- (MASConstraint *)top;
+- (MASConstraint *)right;
+- (MASConstraint *)bottom;
+- (MASConstraint *)leading;
+- (MASConstraint *)trailing;
+- (MASConstraint *)width;
+- (MASConstraint *)height;
+- (MASConstraint *)centerX;
+- (MASConstraint *)centerY;
+- (MASConstraint *)baseline;
+
+- (MASConstraint *)firstBaseline;
+- (MASConstraint *)lastBaseline;
+
+#if TARGET_OS_IPHONE || TARGET_OS_TV
+
+- (MASConstraint *)leftMargin;
+- (MASConstraint *)rightMargin;
+- (MASConstraint *)topMargin;
+- (MASConstraint *)bottomMargin;
+- (MASConstraint *)leadingMargin;
+- (MASConstraint *)trailingMargin;
+- (MASConstraint *)centerXWithinMargins;
+- (MASConstraint *)centerYWithinMargins;
+
+#endif
+
+
+/**
+ *	Sets the constraint debug name
+ */
+- (MASConstraint * (^)(id key))key;
+
+// NSLayoutConstraint constant Setters
+// for use outside of mas_updateConstraints/mas_makeConstraints blocks
+
+/**
+ *	Modifies the NSLayoutConstraint constant,
+ *  only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
+ *  NSLayoutAttributeTop, NSLayoutAttributeLeft, NSLayoutAttributeBottom, NSLayoutAttributeRight
+ */
+- (void)setInsets:(MASEdgeInsets)insets;
+
+/**
+ *	Modifies the NSLayoutConstraint constant,
+ *  only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
+ *  NSLayoutAttributeTop, NSLayoutAttributeLeft, NSLayoutAttributeBottom, NSLayoutAttributeRight
+ */
+- (void)setInset:(CGFloat)inset;
+
+/**
+ *	Modifies the NSLayoutConstraint constant,
+ *  only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
+ *  NSLayoutAttributeWidth, NSLayoutAttributeHeight
+ */
+- (void)setSizeOffset:(CGSize)sizeOffset;
+
+/**
+ *	Modifies the NSLayoutConstraint constant,
+ *  only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
+ *  NSLayoutAttributeCenterX, NSLayoutAttributeCenterY
+ */
+- (void)setCenterOffset:(CGPoint)centerOffset;
+
+/**
+ *	Modifies the NSLayoutConstraint constant
+ */
+- (void)setOffset:(CGFloat)offset;
+
+
+// NSLayoutConstraint Installation support
+
+#if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV)
+/**
+ *  Whether or not to go through the animator proxy when modifying the constraint
+ */
+@property (nonatomic, copy, readonly) MASConstraint *animator;
+#endif
+
+/**
+ *  Activates an NSLayoutConstraint if it's supported by an OS. 
+ *  Invokes install otherwise.
+ */
+- (void)activate;
+
+/**
+ *  Deactivates previously installed/activated NSLayoutConstraint.
+ */
+- (void)deactivate;
+
+/**
+ *	Creates a NSLayoutConstraint and adds it to the appropriate view.
+ */
+- (void)install;
+
+/**
+ *	Removes previously installed NSLayoutConstraint
+ */
+- (void)uninstall;
+
+@end
+
+
+/**
+ *  Convenience auto-boxing macros for MASConstraint methods.
+ *
+ *  Defining MAS_SHORTHAND_GLOBALS will turn on auto-boxing for default syntax.
+ *  A potential drawback of this is that the unprefixed macros will appear in global scope.
+ */
+#define mas_equalTo(...)                 equalTo(MASBoxValue((__VA_ARGS__)))
+#define mas_greaterThanOrEqualTo(...)    greaterThanOrEqualTo(MASBoxValue((__VA_ARGS__)))
+#define mas_lessThanOrEqualTo(...)       lessThanOrEqualTo(MASBoxValue((__VA_ARGS__)))
+
+#define mas_offset(...)                  valueOffset(MASBoxValue((__VA_ARGS__)))
+
+
+#ifdef MAS_SHORTHAND_GLOBALS
+
+#define equalTo(...)                     mas_equalTo(__VA_ARGS__)
+#define greaterThanOrEqualTo(...)        mas_greaterThanOrEqualTo(__VA_ARGS__)
+#define lessThanOrEqualTo(...)           mas_lessThanOrEqualTo(__VA_ARGS__)
+
+#define offset(...)                      mas_offset(__VA_ARGS__)
+
+#endif
+
+
+@interface MASConstraint (AutoboxingSupport)
+
+/**
+ *  Aliases to corresponding relation methods (for shorthand macros)
+ *  Also needed to aid autocompletion
+ */
+- (MASConstraint * (^)(id attr))mas_equalTo;
+- (MASConstraint * (^)(id attr))mas_greaterThanOrEqualTo;
+- (MASConstraint * (^)(id attr))mas_lessThanOrEqualTo;
+
+/**
+ *  A dummy method to aid autocompletion
+ */
+- (MASConstraint * (^)(id offset))mas_offset;
+
+@end

+ 297 - 0
PDFViewer/Masonry/MASConstraint.m

@@ -0,0 +1,297 @@
+//
+//  MASConstraint.m
+//  Masonry
+//
+//  Created by Nick Tymchenko on 1/20/14.
+//
+
+#import "MASConstraint.h"
+#import "MASConstraint+Private.h"
+
+#define MASMethodNotImplemented() \
+    @throw [NSException exceptionWithName:NSInternalInconsistencyException \
+                                   reason:[NSString stringWithFormat:@"You must override %@ in a subclass.", NSStringFromSelector(_cmd)] \
+                                 userInfo:nil]
+
+@implementation MASConstraint
+
+#pragma mark - Init
+
+- (id)init {
+	NSAssert(![self isMemberOfClass:[MASConstraint class]], @"MASConstraint is an abstract class, you should not instantiate it directly.");
+	return [super init];
+}
+
+#pragma mark - NSLayoutRelation proxies
+
+- (MASConstraint * (^)(id))equalTo {
+    return ^id(id attribute) {
+        return self.equalToWithRelation(attribute, NSLayoutRelationEqual);
+    };
+}
+
+- (MASConstraint * (^)(id))mas_equalTo {
+    return ^id(id attribute) {
+        return self.equalToWithRelation(attribute, NSLayoutRelationEqual);
+    };
+}
+
+- (MASConstraint * (^)(id))greaterThanOrEqualTo {
+    return ^id(id attribute) {
+        return self.equalToWithRelation(attribute, NSLayoutRelationGreaterThanOrEqual);
+    };
+}
+
+- (MASConstraint * (^)(id))mas_greaterThanOrEqualTo {
+    return ^id(id attribute) {
+        return self.equalToWithRelation(attribute, NSLayoutRelationGreaterThanOrEqual);
+    };
+}
+
+- (MASConstraint * (^)(id))lessThanOrEqualTo {
+    return ^id(id attribute) {
+        return self.equalToWithRelation(attribute, NSLayoutRelationLessThanOrEqual);
+    };
+}
+
+- (MASConstraint * (^)(id))mas_lessThanOrEqualTo {
+    return ^id(id attribute) {
+        return self.equalToWithRelation(attribute, NSLayoutRelationLessThanOrEqual);
+    };
+}
+
+#pragma mark - MASLayoutPriority proxies
+
+- (MASConstraint * (^)(void))priorityLow {
+    return ^id{
+        self.priority(MASLayoutPriorityDefaultLow);
+        return self;
+    };
+}
+
+- (MASConstraint * (^)(void))priorityMedium {
+    return ^id{
+        self.priority(MASLayoutPriorityDefaultMedium);
+        return self;
+    };
+}
+
+- (MASConstraint * (^)(void))priorityHigh {
+    return ^id{
+        self.priority(MASLayoutPriorityDefaultHigh);
+        return self;
+    };
+}
+
+#pragma mark - NSLayoutConstraint constant proxies
+
+- (MASConstraint * (^)(MASEdgeInsets))insets {
+    return ^id(MASEdgeInsets insets){
+        self.insets = insets;
+        return self;
+    };
+}
+
+- (MASConstraint * (^)(CGFloat))inset {
+    return ^id(CGFloat inset){
+        self.inset = inset;
+        return self;
+    };
+}
+
+- (MASConstraint * (^)(CGSize))sizeOffset {
+    return ^id(CGSize offset) {
+        self.sizeOffset = offset;
+        return self;
+    };
+}
+
+- (MASConstraint * (^)(CGPoint))centerOffset {
+    return ^id(CGPoint offset) {
+        self.centerOffset = offset;
+        return self;
+    };
+}
+
+- (MASConstraint * (^)(CGFloat))offset {
+    return ^id(CGFloat offset){
+        self.offset = offset;
+        return self;
+    };
+}
+
+- (MASConstraint * (^)(NSValue *value))valueOffset {
+    return ^id(NSValue *offset) {
+        NSAssert([offset isKindOfClass:NSValue.class], @"expected an NSValue offset, got: %@", offset);
+        [self setLayoutConstantWithValue:offset];
+        return self;
+    };
+}
+
+- (MASConstraint * (^)(id offset))mas_offset {
+    // Will never be called due to macro
+    return nil;
+}
+
+#pragma mark - NSLayoutConstraint constant setter
+
+- (void)setLayoutConstantWithValue:(NSValue *)value {
+    if ([value isKindOfClass:NSNumber.class]) {
+        self.offset = [(NSNumber *)value doubleValue];
+    } else if (strcmp(value.objCType, @encode(CGPoint)) == 0) {
+        CGPoint point;
+        [value getValue:&point];
+        self.centerOffset = point;
+    } else if (strcmp(value.objCType, @encode(CGSize)) == 0) {
+        CGSize size;
+        [value getValue:&size];
+        self.sizeOffset = size;
+    } else if (strcmp(value.objCType, @encode(MASEdgeInsets)) == 0) {
+        MASEdgeInsets insets;
+        [value getValue:&insets];
+        self.insets = insets;
+    } else {
+        NSAssert(NO, @"attempting to set layout constant with unsupported value: %@", value);
+    }
+}
+
+#pragma mark - Semantic properties
+
+- (MASConstraint *)with {
+    return self;
+}
+
+- (MASConstraint *)and {
+    return self;
+}
+
+#pragma mark - Chaining
+
+- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute __unused)layoutAttribute {
+    MASMethodNotImplemented();
+}
+
+- (MASConstraint *)left {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft];
+}
+
+- (MASConstraint *)top {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTop];
+}
+
+- (MASConstraint *)right {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRight];
+}
+
+- (MASConstraint *)bottom {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottom];
+}
+
+- (MASConstraint *)leading {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeading];
+}
+
+- (MASConstraint *)trailing {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailing];
+}
+
+- (MASConstraint *)width {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeWidth];
+}
+
+- (MASConstraint *)height {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeHeight];
+}
+
+- (MASConstraint *)centerX {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterX];
+}
+
+- (MASConstraint *)centerY {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterY];
+}
+
+- (MASConstraint *)baseline {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBaseline];
+}
+
+- (MASConstraint *)firstBaseline {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeFirstBaseline];
+}
+- (MASConstraint *)lastBaseline {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLastBaseline];
+}
+
+#if TARGET_OS_IPHONE || TARGET_OS_TV
+
+- (MASConstraint *)leftMargin {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeftMargin];
+}
+
+- (MASConstraint *)rightMargin {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRightMargin];
+}
+
+- (MASConstraint *)topMargin {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTopMargin];
+}
+
+- (MASConstraint *)bottomMargin {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottomMargin];
+}
+
+- (MASConstraint *)leadingMargin {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeadingMargin];
+}
+
+- (MASConstraint *)trailingMargin {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailingMargin];
+}
+
+- (MASConstraint *)centerXWithinMargins {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterXWithinMargins];
+}
+
+- (MASConstraint *)centerYWithinMargins {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterYWithinMargins];
+}
+
+#endif
+
+#pragma mark - Abstract
+
+- (MASConstraint * (^)(CGFloat multiplier))multipliedBy { MASMethodNotImplemented(); }
+
+- (MASConstraint * (^)(CGFloat divider))dividedBy { MASMethodNotImplemented(); }
+
+- (MASConstraint * (^)(MASLayoutPriority priority))priority { MASMethodNotImplemented(); }
+
+- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation { MASMethodNotImplemented(); }
+
+- (MASConstraint * (^)(id key))key { MASMethodNotImplemented(); }
+
+- (void)setInsets:(MASEdgeInsets __unused)insets { MASMethodNotImplemented(); }
+
+- (void)setInset:(CGFloat __unused)inset { MASMethodNotImplemented(); }
+
+- (void)setSizeOffset:(CGSize __unused)sizeOffset { MASMethodNotImplemented(); }
+
+- (void)setCenterOffset:(CGPoint __unused)centerOffset { MASMethodNotImplemented(); }
+
+- (void)setOffset:(CGFloat __unused)offset { MASMethodNotImplemented(); }
+
+#if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV)
+
+- (MASConstraint *)animator { MASMethodNotImplemented(); }
+
+#endif
+
+- (void)activate { MASMethodNotImplemented(); }
+
+- (void)deactivate { MASMethodNotImplemented(); }
+
+- (void)install { MASMethodNotImplemented(); }
+
+- (void)uninstall { MASMethodNotImplemented(); }
+
+@end

+ 138 - 0
PDFViewer/Masonry/MASConstraintMaker.h

@@ -0,0 +1,138 @@
+//
+//  MASConstraintMaker.h
+//  Masonry
+//
+//  Created by Jonas Budelmann on 20/07/13.
+//  Copyright (c) 2013 cloudling. All rights reserved.
+//
+
+#import "MASConstraint.h"
+#import "MASUtilities.h"
+
+typedef NS_OPTIONS(NSInteger, MASAttribute) {
+    MASAttributeLeft = 1 << NSLayoutAttributeLeft,
+    MASAttributeRight = 1 << NSLayoutAttributeRight,
+    MASAttributeTop = 1 << NSLayoutAttributeTop,
+    MASAttributeBottom = 1 << NSLayoutAttributeBottom,
+    MASAttributeLeading = 1 << NSLayoutAttributeLeading,
+    MASAttributeTrailing = 1 << NSLayoutAttributeTrailing,
+    MASAttributeWidth = 1 << NSLayoutAttributeWidth,
+    MASAttributeHeight = 1 << NSLayoutAttributeHeight,
+    MASAttributeCenterX = 1 << NSLayoutAttributeCenterX,
+    MASAttributeCenterY = 1 << NSLayoutAttributeCenterY,
+    MASAttributeBaseline = 1 << NSLayoutAttributeBaseline,
+
+    MASAttributeFirstBaseline = 1 << NSLayoutAttributeFirstBaseline,
+    MASAttributeLastBaseline = 1 << NSLayoutAttributeLastBaseline,
+    
+#if TARGET_OS_IPHONE || TARGET_OS_TV
+    
+    MASAttributeLeftMargin = 1 << NSLayoutAttributeLeftMargin,
+    MASAttributeRightMargin = 1 << NSLayoutAttributeRightMargin,
+    MASAttributeTopMargin = 1 << NSLayoutAttributeTopMargin,
+    MASAttributeBottomMargin = 1 << NSLayoutAttributeBottomMargin,
+    MASAttributeLeadingMargin = 1 << NSLayoutAttributeLeadingMargin,
+    MASAttributeTrailingMargin = 1 << NSLayoutAttributeTrailingMargin,
+    MASAttributeCenterXWithinMargins = 1 << NSLayoutAttributeCenterXWithinMargins,
+    MASAttributeCenterYWithinMargins = 1 << NSLayoutAttributeCenterYWithinMargins,
+
+#endif
+    
+};
+
+/**
+ *  Provides factory methods for creating MASConstraints.
+ *  Constraints are collected until they are ready to be installed
+ *
+ */
+@interface MASConstraintMaker : NSObject
+
+/**
+ *	The following properties return a new MASViewConstraint
+ *  with the first item set to the makers associated view and the appropriate MASViewAttribute
+ */
+@property (nonatomic, strong, readonly) MASConstraint *left;
+@property (nonatomic, strong, readonly) MASConstraint *top;
+@property (nonatomic, strong, readonly) MASConstraint *right;
+@property (nonatomic, strong, readonly) MASConstraint *bottom;
+@property (nonatomic, strong, readonly) MASConstraint *leading;
+@property (nonatomic, strong, readonly) MASConstraint *trailing;
+@property (nonatomic, strong, readonly) MASConstraint *width;
+@property (nonatomic, strong, readonly) MASConstraint *height;
+@property (nonatomic, strong, readonly) MASConstraint *centerX;
+@property (nonatomic, strong, readonly) MASConstraint *centerY;
+@property (nonatomic, strong, readonly) MASConstraint *baseline;
+
+@property (nonatomic, strong, readonly) MASConstraint *firstBaseline;
+@property (nonatomic, strong, readonly) MASConstraint *lastBaseline;
+
+#if TARGET_OS_IPHONE || TARGET_OS_TV
+
+@property (nonatomic, strong, readonly) MASConstraint *leftMargin;
+@property (nonatomic, strong, readonly) MASConstraint *rightMargin;
+@property (nonatomic, strong, readonly) MASConstraint *topMargin;
+@property (nonatomic, strong, readonly) MASConstraint *bottomMargin;
+@property (nonatomic, strong, readonly) MASConstraint *leadingMargin;
+@property (nonatomic, strong, readonly) MASConstraint *trailingMargin;
+@property (nonatomic, strong, readonly) MASConstraint *centerXWithinMargins;
+@property (nonatomic, strong, readonly) MASConstraint *centerYWithinMargins;
+
+#endif
+
+/**
+ *  Returns a block which creates a new MASCompositeConstraint with the first item set
+ *  to the makers associated view and children corresponding to the set bits in the
+ *  MASAttribute parameter. Combine multiple attributes via binary-or.
+ */
+@property (nonatomic, strong, readonly) MASConstraint *(^attributes)(MASAttribute attrs);
+
+/**
+ *	Creates a MASCompositeConstraint with type MASCompositeConstraintTypeEdges
+ *  which generates the appropriate MASViewConstraint children (top, left, bottom, right)
+ *  with the first item set to the makers associated view
+ */
+@property (nonatomic, strong, readonly) MASConstraint *edges;
+
+/**
+ *	Creates a MASCompositeConstraint with type MASCompositeConstraintTypeSize
+ *  which generates the appropriate MASViewConstraint children (width, height)
+ *  with the first item set to the makers associated view
+ */
+@property (nonatomic, strong, readonly) MASConstraint *size;
+
+/**
+ *	Creates a MASCompositeConstraint with type MASCompositeConstraintTypeCenter
+ *  which generates the appropriate MASViewConstraint children (centerX, centerY)
+ *  with the first item set to the makers associated view
+ */
+@property (nonatomic, strong, readonly) MASConstraint *center;
+
+/**
+ *  Whether or not to check for an existing constraint instead of adding constraint
+ */
+@property (nonatomic, assign) BOOL updateExisting;
+
+/**
+ *  Whether or not to remove existing constraints prior to installing
+ */
+@property (nonatomic, assign) BOOL removeExisting;
+
+/**
+ *	initialises the maker with a default view
+ *
+ *	@param	view	any MASConstraint are created with this view as the first item
+ *
+ *	@return	a new MASConstraintMaker
+ */
+- (id)initWithView:(MAS_VIEW *)view;
+
+/**
+ *	Calls install method on any MASConstraints which have been created by this maker
+ *
+ *	@return	an array of all the installed MASConstraints
+ */
+- (NSArray *)install;
+
+- (MASConstraint * (^)(dispatch_block_t))group;
+
+@end

+ 261 - 0
PDFViewer/Masonry/MASConstraintMaker.m

@@ -0,0 +1,261 @@
+//
+//  MASConstraintMaker.m
+//  Masonry
+//
+//  Created by Jonas Budelmann on 20/07/13.
+//  Copyright (c) 2013 cloudling. All rights reserved.
+//
+
+#import "MASConstraintMaker.h"
+#import "MASViewConstraint.h"
+#import "MASCompositeConstraint.h"
+#import "MASConstraint+Private.h"
+#import "MASViewAttribute.h"
+#import "View+MASAdditions.h"
+
+@interface MASConstraintMaker () <MASConstraintDelegate>
+
+@property (nonatomic, weak) MAS_VIEW *view;
+@property (nonatomic, strong) NSMutableArray *constraints;
+
+@end
+
+@implementation MASConstraintMaker
+
+- (id)initWithView:(MAS_VIEW *)view {
+    self = [super init];
+    if (!self) return nil;
+    
+    self.view = view;
+    self.constraints = NSMutableArray.new;
+    
+    return self;
+}
+
+- (NSArray *)install {
+    if (self.removeExisting) {
+        NSArray *installedConstraints = [MASViewConstraint installedConstraintsForView:self.view];
+        for (MASConstraint *constraint in installedConstraints) {
+            [constraint uninstall];
+        }
+    }
+    NSArray *constraints = self.constraints.copy;
+    for (MASConstraint *constraint in constraints) {
+        constraint.updateExisting = self.updateExisting;
+        [constraint install];
+    }
+    [self.constraints removeAllObjects];
+    return constraints;
+}
+
+#pragma mark - MASConstraintDelegate
+
+- (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint {
+    NSUInteger index = [self.constraints indexOfObject:constraint];
+    NSAssert(index != NSNotFound, @"Could not find constraint %@", constraint);
+    [self.constraints replaceObjectAtIndex:index withObject:replacementConstraint];
+}
+
+- (MASConstraint *)constraint:(MASConstraint *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
+    MASViewAttribute *viewAttribute = [[MASViewAttribute alloc] initWithView:self.view layoutAttribute:layoutAttribute];
+    MASViewConstraint *newConstraint = [[MASViewConstraint alloc] initWithFirstViewAttribute:viewAttribute];
+    if ([constraint isKindOfClass:MASViewConstraint.class]) {
+        //replace with composite constraint
+        NSArray *children = @[constraint, newConstraint];
+        MASCompositeConstraint *compositeConstraint = [[MASCompositeConstraint alloc] initWithChildren:children];
+        compositeConstraint.delegate = self;
+        [self constraint:constraint shouldBeReplacedWithConstraint:compositeConstraint];
+        return compositeConstraint;
+    }
+    if (!constraint) {
+        newConstraint.delegate = self;
+        [self.constraints addObject:newConstraint];
+    }
+    return newConstraint;
+}
+
+- (MASConstraint *)addConstraintWithAttributes:(MASAttribute)attrs {
+    __unused MASAttribute anyAttribute = (MASAttributeLeft | MASAttributeRight | MASAttributeTop | MASAttributeBottom | MASAttributeLeading
+                                          | MASAttributeTrailing | MASAttributeWidth | MASAttributeHeight | MASAttributeCenterX
+                                          | MASAttributeCenterY | MASAttributeBaseline
+                                          | MASAttributeFirstBaseline | MASAttributeLastBaseline
+#if TARGET_OS_IPHONE || TARGET_OS_TV
+                                          | MASAttributeLeftMargin | MASAttributeRightMargin | MASAttributeTopMargin | MASAttributeBottomMargin
+                                          | MASAttributeLeadingMargin | MASAttributeTrailingMargin | MASAttributeCenterXWithinMargins
+                                          | MASAttributeCenterYWithinMargins
+#endif
+                                          );
+    
+    NSAssert((attrs & anyAttribute) != 0, @"You didn't pass any attribute to make.attributes(...)");
+    
+    NSMutableArray *attributes = [NSMutableArray array];
+    
+    if (attrs & MASAttributeLeft) [attributes addObject:self.view.mas_left];
+    if (attrs & MASAttributeRight) [attributes addObject:self.view.mas_right];
+    if (attrs & MASAttributeTop) [attributes addObject:self.view.mas_top];
+    if (attrs & MASAttributeBottom) [attributes addObject:self.view.mas_bottom];
+    if (attrs & MASAttributeLeading) [attributes addObject:self.view.mas_leading];
+    if (attrs & MASAttributeTrailing) [attributes addObject:self.view.mas_trailing];
+    if (attrs & MASAttributeWidth) [attributes addObject:self.view.mas_width];
+    if (attrs & MASAttributeHeight) [attributes addObject:self.view.mas_height];
+    if (attrs & MASAttributeCenterX) [attributes addObject:self.view.mas_centerX];
+    if (attrs & MASAttributeCenterY) [attributes addObject:self.view.mas_centerY];
+    if (attrs & MASAttributeBaseline) [attributes addObject:self.view.mas_baseline];
+    if (attrs & MASAttributeFirstBaseline) [attributes addObject:self.view.mas_firstBaseline];
+    if (attrs & MASAttributeLastBaseline) [attributes addObject:self.view.mas_lastBaseline];
+    
+#if TARGET_OS_IPHONE || TARGET_OS_TV
+    
+    if (attrs & MASAttributeLeftMargin) [attributes addObject:self.view.mas_leftMargin];
+    if (attrs & MASAttributeRightMargin) [attributes addObject:self.view.mas_rightMargin];
+    if (attrs & MASAttributeTopMargin) [attributes addObject:self.view.mas_topMargin];
+    if (attrs & MASAttributeBottomMargin) [attributes addObject:self.view.mas_bottomMargin];
+    if (attrs & MASAttributeLeadingMargin) [attributes addObject:self.view.mas_leadingMargin];
+    if (attrs & MASAttributeTrailingMargin) [attributes addObject:self.view.mas_trailingMargin];
+    if (attrs & MASAttributeCenterXWithinMargins) [attributes addObject:self.view.mas_centerXWithinMargins];
+    if (attrs & MASAttributeCenterYWithinMargins) [attributes addObject:self.view.mas_centerYWithinMargins];
+    
+#endif
+    
+    NSMutableArray *children = [NSMutableArray arrayWithCapacity:attributes.count];
+    
+    for (MASViewAttribute *a in attributes) {
+        [children addObject:[[MASViewConstraint alloc] initWithFirstViewAttribute:a]];
+    }
+    
+    MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithChildren:children];
+    constraint.delegate = self;
+    [self.constraints addObject:constraint];
+    return constraint;
+}
+
+#pragma mark - standard Attributes
+
+- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
+    return [self constraint:nil addConstraintWithLayoutAttribute:layoutAttribute];
+}
+
+- (MASConstraint *)left {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft];
+}
+
+- (MASConstraint *)top {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTop];
+}
+
+- (MASConstraint *)right {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRight];
+}
+
+- (MASConstraint *)bottom {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottom];
+}
+
+- (MASConstraint *)leading {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeading];
+}
+
+- (MASConstraint *)trailing {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailing];
+}
+
+- (MASConstraint *)width {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeWidth];
+}
+
+- (MASConstraint *)height {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeHeight];
+}
+
+- (MASConstraint *)centerX {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterX];
+}
+
+- (MASConstraint *)centerY {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterY];
+}
+
+- (MASConstraint *)baseline {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBaseline];
+}
+
+- (MASConstraint *(^)(MASAttribute))attributes {
+    return ^(MASAttribute attrs){
+        return [self addConstraintWithAttributes:attrs];
+    };
+}
+
+- (MASConstraint *)firstBaseline {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeFirstBaseline];
+}
+
+- (MASConstraint *)lastBaseline {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLastBaseline];
+}
+
+#if TARGET_OS_IPHONE || TARGET_OS_TV
+
+- (MASConstraint *)leftMargin {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeftMargin];
+}
+
+- (MASConstraint *)rightMargin {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRightMargin];
+}
+
+- (MASConstraint *)topMargin {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTopMargin];
+}
+
+- (MASConstraint *)bottomMargin {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottomMargin];
+}
+
+- (MASConstraint *)leadingMargin {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeadingMargin];
+}
+
+- (MASConstraint *)trailingMargin {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailingMargin];
+}
+
+- (MASConstraint *)centerXWithinMargins {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterXWithinMargins];
+}
+
+- (MASConstraint *)centerYWithinMargins {
+    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterYWithinMargins];
+}
+
+#endif
+
+
+#pragma mark - composite Attributes
+
+- (MASConstraint *)edges {
+    return [self addConstraintWithAttributes:MASAttributeTop | MASAttributeLeft | MASAttributeRight | MASAttributeBottom];
+}
+
+- (MASConstraint *)size {
+    return [self addConstraintWithAttributes:MASAttributeWidth | MASAttributeHeight];
+}
+
+- (MASConstraint *)center {
+    return [self addConstraintWithAttributes:MASAttributeCenterX | MASAttributeCenterY];
+}
+
+#pragma mark - grouping
+
+- (MASConstraint *(^)(dispatch_block_t group))group {
+    return ^id(dispatch_block_t group) {
+        NSInteger previousCount = self.constraints.count;
+        group();
+
+        NSArray *children = [self.constraints subarrayWithRange:NSMakeRange(previousCount, self.constraints.count - previousCount)];
+        MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithChildren:children];
+        constraint.delegate = self;
+        return constraint;
+    };
+}
+
+@end

+ 22 - 0
PDFViewer/Masonry/MASLayoutConstraint.h

@@ -0,0 +1,22 @@
+//
+//  MASLayoutConstraint.h
+//  Masonry
+//
+//  Created by Jonas Budelmann on 3/08/13.
+//  Copyright (c) 2013 Jonas Budelmann. All rights reserved.
+//
+
+#import "MASUtilities.h"
+
+/**
+ *	When you are debugging or printing the constraints attached to a view this subclass
+ *  makes it easier to identify which constraints have been created via Masonry
+ */
+@interface MASLayoutConstraint : NSLayoutConstraint
+
+/**
+ *	a key to associate with this constraint
+ */
+@property (nonatomic, strong) id mas_key;
+
+@end

+ 13 - 0
PDFViewer/Masonry/MASLayoutConstraint.m

@@ -0,0 +1,13 @@
+//
+//  MASLayoutConstraint.m
+//  Masonry
+//
+//  Created by Jonas Budelmann on 3/08/13.
+//  Copyright (c) 2013 Jonas Budelmann. All rights reserved.
+//
+
+#import "MASLayoutConstraint.h"
+
+@implementation MASLayoutConstraint
+
+@end

+ 136 - 0
PDFViewer/Masonry/MASUtilities.h

@@ -0,0 +1,136 @@
+//
+//  MASUtilities.h
+//  Masonry
+//
+//  Created by Jonas Budelmann on 19/08/13.
+//  Copyright (c) 2013 Jonas Budelmann. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+
+
+#if TARGET_OS_IPHONE || TARGET_OS_TV
+
+    #import <UIKit/UIKit.h>
+    #define MAS_VIEW UIView
+    #define MAS_VIEW_CONTROLLER UIViewController
+    #define MASEdgeInsets UIEdgeInsets
+
+    typedef UILayoutPriority MASLayoutPriority;
+    static const MASLayoutPriority MASLayoutPriorityRequired = UILayoutPriorityRequired;
+    static const MASLayoutPriority MASLayoutPriorityDefaultHigh = UILayoutPriorityDefaultHigh;
+    static const MASLayoutPriority MASLayoutPriorityDefaultMedium = 500;
+    static const MASLayoutPriority MASLayoutPriorityDefaultLow = UILayoutPriorityDefaultLow;
+    static const MASLayoutPriority MASLayoutPriorityFittingSizeLevel = UILayoutPriorityFittingSizeLevel;
+
+#elif TARGET_OS_MAC
+
+    #import <AppKit/AppKit.h>
+    #define MAS_VIEW NSView
+    #define MASEdgeInsets NSEdgeInsets
+
+    typedef NSLayoutPriority MASLayoutPriority;
+    static const MASLayoutPriority MASLayoutPriorityRequired = NSLayoutPriorityRequired;
+    static const MASLayoutPriority MASLayoutPriorityDefaultHigh = NSLayoutPriorityDefaultHigh;
+    static const MASLayoutPriority MASLayoutPriorityDragThatCanResizeWindow = NSLayoutPriorityDragThatCanResizeWindow;
+    static const MASLayoutPriority MASLayoutPriorityDefaultMedium = 501;
+    static const MASLayoutPriority MASLayoutPriorityWindowSizeStayPut = NSLayoutPriorityWindowSizeStayPut;
+    static const MASLayoutPriority MASLayoutPriorityDragThatCannotResizeWindow = NSLayoutPriorityDragThatCannotResizeWindow;
+    static const MASLayoutPriority MASLayoutPriorityDefaultLow = NSLayoutPriorityDefaultLow;
+    static const MASLayoutPriority MASLayoutPriorityFittingSizeCompression = NSLayoutPriorityFittingSizeCompression;
+
+#endif
+
+/**
+ *	Allows you to attach keys to objects matching the variable names passed.
+ *
+ *  view1.mas_key = @"view1", view2.mas_key = @"view2";
+ *
+ *  is equivalent to:
+ *
+ *  MASAttachKeys(view1, view2);
+ */
+#define MASAttachKeys(...)                                                        \
+    {                                                                             \
+        NSDictionary *keyPairs = NSDictionaryOfVariableBindings(__VA_ARGS__);     \
+        for (id key in keyPairs.allKeys) {                                        \
+            id obj = keyPairs[key];                                               \
+            NSAssert([obj respondsToSelector:@selector(setMas_key:)],             \
+                     @"Cannot attach mas_key to %@", obj);                        \
+            [obj setMas_key:key];                                                 \
+        }                                                                         \
+    }
+
+/**
+ *  Used to create object hashes
+ *  Based on http://www.mikeash.com/pyblog/friday-qa-2010-06-18-implementing-equality-and-hashing.html
+ */
+#define MAS_NSUINT_BIT (CHAR_BIT * sizeof(NSUInteger))
+#define MAS_NSUINTROTATE(val, howmuch) ((((NSUInteger)val) << howmuch) | (((NSUInteger)val) >> (MAS_NSUINT_BIT - howmuch)))
+
+/**
+ *  Given a scalar or struct value, wraps it in NSValue
+ *  Based on EXPObjectify: https://github.com/specta/expecta
+ */
+static inline id _MASBoxValue(const char *type, ...) {
+    va_list v;
+    va_start(v, type);
+    id obj = nil;
+    if (strcmp(type, @encode(id)) == 0) {
+        id actual = va_arg(v, id);
+        obj = actual;
+    } else if (strcmp(type, @encode(CGPoint)) == 0) {
+        CGPoint actual = (CGPoint)va_arg(v, CGPoint);
+        obj = [NSValue value:&actual withObjCType:type];
+    } else if (strcmp(type, @encode(CGSize)) == 0) {
+        CGSize actual = (CGSize)va_arg(v, CGSize);
+        obj = [NSValue value:&actual withObjCType:type];
+    } else if (strcmp(type, @encode(MASEdgeInsets)) == 0) {
+        MASEdgeInsets actual = (MASEdgeInsets)va_arg(v, MASEdgeInsets);
+        obj = [NSValue value:&actual withObjCType:type];
+    } else if (strcmp(type, @encode(double)) == 0) {
+        double actual = (double)va_arg(v, double);
+        obj = [NSNumber numberWithDouble:actual];
+    } else if (strcmp(type, @encode(float)) == 0) {
+        float actual = (float)va_arg(v, double);
+        obj = [NSNumber numberWithFloat:actual];
+    } else if (strcmp(type, @encode(int)) == 0) {
+        int actual = (int)va_arg(v, int);
+        obj = [NSNumber numberWithInt:actual];
+    } else if (strcmp(type, @encode(long)) == 0) {
+        long actual = (long)va_arg(v, long);
+        obj = [NSNumber numberWithLong:actual];
+    } else if (strcmp(type, @encode(long long)) == 0) {
+        long long actual = (long long)va_arg(v, long long);
+        obj = [NSNumber numberWithLongLong:actual];
+    } else if (strcmp(type, @encode(short)) == 0) {
+        short actual = (short)va_arg(v, int);
+        obj = [NSNumber numberWithShort:actual];
+    } else if (strcmp(type, @encode(char)) == 0) {
+        char actual = (char)va_arg(v, int);
+        obj = [NSNumber numberWithChar:actual];
+    } else if (strcmp(type, @encode(bool)) == 0) {
+        bool actual = (bool)va_arg(v, int);
+        obj = [NSNumber numberWithBool:actual];
+    } else if (strcmp(type, @encode(unsigned char)) == 0) {
+        unsigned char actual = (unsigned char)va_arg(v, unsigned int);
+        obj = [NSNumber numberWithUnsignedChar:actual];
+    } else if (strcmp(type, @encode(unsigned int)) == 0) {
+        unsigned int actual = (unsigned int)va_arg(v, unsigned int);
+        obj = [NSNumber numberWithUnsignedInt:actual];
+    } else if (strcmp(type, @encode(unsigned long)) == 0) {
+        unsigned long actual = (unsigned long)va_arg(v, unsigned long);
+        obj = [NSNumber numberWithUnsignedLong:actual];
+    } else if (strcmp(type, @encode(unsigned long long)) == 0) {
+        unsigned long long actual = (unsigned long long)va_arg(v, unsigned long long);
+        obj = [NSNumber numberWithUnsignedLongLong:actual];
+    } else if (strcmp(type, @encode(unsigned short)) == 0) {
+        unsigned short actual = (unsigned short)va_arg(v, unsigned int);
+        obj = [NSNumber numberWithUnsignedShort:actual];
+    }
+    va_end(v);
+    return obj;
+}
+
+#define MASBoxValue(value) _MASBoxValue(@encode(__typeof__((value))), (value))

+ 49 - 0
PDFViewer/Masonry/MASViewAttribute.h

@@ -0,0 +1,49 @@
+//
+//  MASViewAttribute.h
+//  Masonry
+//
+//  Created by Jonas Budelmann on 21/07/13.
+//  Copyright (c) 2013 cloudling. All rights reserved.
+//
+
+#import "MASUtilities.h"
+
+/**
+ *  An immutable tuple which stores the view and the related NSLayoutAttribute.
+ *  Describes part of either the left or right hand side of a constraint equation
+ */
+@interface MASViewAttribute : NSObject
+
+/**
+ *  The view which the reciever relates to. Can be nil if item is not a view.
+ */
+@property (nonatomic, weak, readonly) MAS_VIEW *view;
+
+/**
+ *  The item which the reciever relates to.
+ */
+@property (nonatomic, weak, readonly) id item;
+
+/**
+ *  The attribute which the reciever relates to
+ */
+@property (nonatomic, assign, readonly) NSLayoutAttribute layoutAttribute;
+
+/**
+ *  Convenience initializer.
+ */
+- (id)initWithView:(MAS_VIEW *)view layoutAttribute:(NSLayoutAttribute)layoutAttribute;
+
+/**
+ *  The designated initializer.
+ */
+- (id)initWithView:(MAS_VIEW *)view item:(id)item layoutAttribute:(NSLayoutAttribute)layoutAttribute;
+
+/**
+ *	Determine whether the layoutAttribute is a size attribute
+ *
+ *	@return	YES if layoutAttribute is equal to NSLayoutAttributeWidth or NSLayoutAttributeHeight
+ */
+- (BOOL)isSizeAttribute;
+
+@end

+ 46 - 0
PDFViewer/Masonry/MASViewAttribute.m

@@ -0,0 +1,46 @@
+//
+//  MASViewAttribute.m
+//  Masonry
+//
+//  Created by Jonas Budelmann on 21/07/13.
+//  Copyright (c) 2013 cloudling. All rights reserved.
+//
+
+#import "MASViewAttribute.h"
+
+@implementation MASViewAttribute
+
+- (id)initWithView:(MAS_VIEW *)view layoutAttribute:(NSLayoutAttribute)layoutAttribute {
+    self = [self initWithView:view item:view layoutAttribute:layoutAttribute];
+    return self;
+}
+
+- (id)initWithView:(MAS_VIEW *)view item:(id)item layoutAttribute:(NSLayoutAttribute)layoutAttribute {
+    self = [super init];
+    if (!self) return nil;
+    
+    _view = view;
+    _item = item;
+    _layoutAttribute = layoutAttribute;
+    
+    return self;
+}
+
+- (BOOL)isSizeAttribute {
+    return self.layoutAttribute == NSLayoutAttributeWidth
+        || self.layoutAttribute == NSLayoutAttributeHeight;
+}
+
+- (BOOL)isEqual:(MASViewAttribute *)viewAttribute {
+    if ([viewAttribute isKindOfClass:self.class]) {
+        return self.view == viewAttribute.view
+            && self.layoutAttribute == viewAttribute.layoutAttribute;
+    }
+    return [super isEqual:viewAttribute];
+}
+
+- (NSUInteger)hash {
+    return MAS_NSUINTROTATE([self.view hash], MAS_NSUINT_BIT / 2) ^ self.layoutAttribute;
+}
+
+@end

+ 48 - 0
PDFViewer/Masonry/MASViewConstraint.h

@@ -0,0 +1,48 @@
+//
+//  MASViewConstraint.h
+//  Masonry
+//
+//  Created by Jonas Budelmann on 20/07/13.
+//  Copyright (c) 2013 cloudling. All rights reserved.
+//
+
+#import "MASViewAttribute.h"
+#import "MASConstraint.h"
+#import "MASLayoutConstraint.h"
+#import "MASUtilities.h"
+
+/**
+ *  A single constraint.
+ *  Contains the attributes neccessary for creating a NSLayoutConstraint and adding it to the appropriate view
+ */
+@interface MASViewConstraint : MASConstraint <NSCopying>
+
+/**
+ *	First item/view and first attribute of the NSLayoutConstraint
+ */
+@property (nonatomic, strong, readonly) MASViewAttribute *firstViewAttribute;
+
+/**
+ *	Second item/view and second attribute of the NSLayoutConstraint
+ */
+@property (nonatomic, strong, readonly) MASViewAttribute *secondViewAttribute;
+
+/**
+ *	initialises the MASViewConstraint with the first part of the equation
+ *
+ *	@param	firstViewAttribute	view.mas_left, view.mas_width etc.
+ *
+ *	@return	a new view constraint
+ */
+- (id)initWithFirstViewAttribute:(MASViewAttribute *)firstViewAttribute;
+
+/**
+ *  Returns all MASViewConstraints installed with this view as a first item.
+ *
+ *  @param  view  A view to retrieve constraints for.
+ *
+ *  @return An array of MASViewConstraints.
+ */
++ (NSArray *)installedConstraintsForView:(MAS_VIEW *)view;
+
+@end

+ 406 - 0
PDFViewer/Masonry/MASViewConstraint.m

@@ -0,0 +1,406 @@
+//
+//  MASViewConstraint.m
+//  Masonry
+//
+//  Created by Jonas Budelmann on 20/07/13.
+//  Copyright (c) 2013 cloudling. All rights reserved.
+//
+
+#import "MASViewConstraint.h"
+#import "MASConstraint+Private.h"
+#import "MASCompositeConstraint.h"
+#import "MASLayoutConstraint.h"
+#import "View+MASAdditions.h"
+#import <objc/runtime.h>
+
+@interface MAS_VIEW (MASConstraints)
+
+@property (nonatomic, readonly) NSMutableSet *mas_installedConstraints;
+
+@end
+
+@implementation MAS_VIEW (MASConstraints)
+
+static char kInstalledConstraintsKey;
+
+- (NSMutableSet *)mas_installedConstraints {
+    NSMutableSet *constraints = objc_getAssociatedObject(self, &kInstalledConstraintsKey);
+    if (!constraints) {
+        constraints = [NSMutableSet set];
+        objc_setAssociatedObject(self, &kInstalledConstraintsKey, constraints, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+    }
+    return constraints;
+}
+
+@end
+
+
+@interface MASViewConstraint ()
+
+@property (nonatomic, strong, readwrite) MASViewAttribute *secondViewAttribute;
+@property (nonatomic, weak) MAS_VIEW *installedView;
+@property (nonatomic, weak) MASLayoutConstraint *layoutConstraint;
+@property (nonatomic, assign) NSLayoutRelation layoutRelation;
+@property (nonatomic, assign) MASLayoutPriority layoutPriority;
+@property (nonatomic, assign) CGFloat layoutMultiplier;
+@property (nonatomic, assign) CGFloat layoutConstant;
+@property (nonatomic, assign) BOOL hasLayoutRelation;
+@property (nonatomic, strong) id mas_key;
+@property (nonatomic, assign) BOOL useAnimator;
+
+@end
+
+@implementation MASViewConstraint
+
+- (id)initWithFirstViewAttribute:(MASViewAttribute *)firstViewAttribute {
+    self = [super init];
+    if (!self) return nil;
+    
+    _firstViewAttribute = firstViewAttribute;
+    self.layoutPriority = MASLayoutPriorityRequired;
+    self.layoutMultiplier = 1;
+    
+    return self;
+}
+
+#pragma mark - NSCoping
+
+- (id)copyWithZone:(NSZone __unused *)zone {
+    MASViewConstraint *constraint = [[MASViewConstraint alloc] initWithFirstViewAttribute:self.firstViewAttribute];
+    constraint.layoutConstant = self.layoutConstant;
+    constraint.layoutRelation = self.layoutRelation;
+    constraint.layoutPriority = self.layoutPriority;
+    constraint.layoutMultiplier = self.layoutMultiplier;
+    constraint.delegate = self.delegate;
+    return constraint;
+}
+
+#pragma mark - Public
+
++ (NSArray *)installedConstraintsForView:(MAS_VIEW *)view {
+    return [view.mas_installedConstraints allObjects];
+}
+
+#pragma mark - Private
+
+- (void)setLayoutConstant:(CGFloat)layoutConstant {
+    _layoutConstant = layoutConstant;
+
+#if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV)
+    if (self.useAnimator) {
+        [self.layoutConstraint.animator setConstant:layoutConstant];
+    } else {
+        self.layoutConstraint.constant = layoutConstant;
+    }
+#else
+    self.layoutConstraint.constant = layoutConstant;
+#endif
+}
+
+- (void)setLayoutRelation:(NSLayoutRelation)layoutRelation {
+    _layoutRelation = layoutRelation;
+    self.hasLayoutRelation = YES;
+}
+
+- (BOOL)supportsActiveProperty {
+    return [self.layoutConstraint respondsToSelector:@selector(isActive)];
+}
+
+- (BOOL)isActive {
+    BOOL active = YES;
+    if ([self supportsActiveProperty]) {
+        active = [self.layoutConstraint isActive];
+    }
+
+    return active;
+}
+
+- (BOOL)hasBeenInstalled {
+    return (self.layoutConstraint != nil) && [self isActive];
+}
+
+- (void)setSecondViewAttribute:(id)secondViewAttribute {
+    if ([secondViewAttribute isKindOfClass:NSValue.class]) {
+        [self setLayoutConstantWithValue:secondViewAttribute];
+    } else if ([secondViewAttribute isKindOfClass:MAS_VIEW.class]) {
+        _secondViewAttribute = [[MASViewAttribute alloc] initWithView:secondViewAttribute layoutAttribute:self.firstViewAttribute.layoutAttribute];
+    } else if ([secondViewAttribute isKindOfClass:MASViewAttribute.class]) {
+        MASViewAttribute *attr = secondViewAttribute;
+        if (attr.layoutAttribute == NSLayoutAttributeNotAnAttribute) {
+            _secondViewAttribute = [[MASViewAttribute alloc] initWithView:attr.view item:attr.item layoutAttribute:self.firstViewAttribute.layoutAttribute];;
+        } else {
+            _secondViewAttribute = secondViewAttribute;
+        }
+    } else {
+        NSAssert(NO, @"attempting to add unsupported attribute: %@", secondViewAttribute);
+    }
+}
+
+#pragma mark - NSLayoutConstraint multiplier proxies
+
+- (MASConstraint * (^)(CGFloat))multipliedBy {
+    return ^id(CGFloat multiplier) {
+        NSAssert(!self.hasBeenInstalled,
+                 @"Cannot modify constraint multiplier after it has been installed");
+        
+        self.layoutMultiplier = multiplier;
+        return self;
+    };
+}
+
+
+- (MASConstraint * (^)(CGFloat))dividedBy {
+    return ^id(CGFloat divider) {
+        NSAssert(!self.hasBeenInstalled,
+                 @"Cannot modify constraint multiplier after it has been installed");
+
+        self.layoutMultiplier = 1.0/divider;
+        return self;
+    };
+}
+
+#pragma mark - MASLayoutPriority proxy
+
+- (MASConstraint * (^)(MASLayoutPriority))priority {
+    return ^id(MASLayoutPriority priority) {
+        NSAssert(!self.hasBeenInstalled,
+                 @"Cannot modify constraint priority after it has been installed");
+        
+        self.layoutPriority = priority;
+        return self;
+    };
+}
+
+#pragma mark - NSLayoutRelation proxy
+
+- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation {
+    return ^id(id attribute, NSLayoutRelation relation) {
+        if ([attribute isKindOfClass:NSArray.class]) {
+            NSAssert(!self.hasLayoutRelation, @"Redefinition of constraint relation");
+            NSMutableArray *children = NSMutableArray.new;
+            for (id attr in attribute) {
+                MASViewConstraint *viewConstraint = [self copy];
+                viewConstraint.layoutRelation = relation;
+                viewConstraint.secondViewAttribute = attr;
+                [children addObject:viewConstraint];
+            }
+            MASCompositeConstraint *compositeConstraint = [[MASCompositeConstraint alloc] initWithChildren:children];
+            compositeConstraint.delegate = self.delegate;
+            [self.delegate constraint:self shouldBeReplacedWithConstraint:compositeConstraint];
+            return compositeConstraint;
+        } else {
+            NSAssert(!self.hasLayoutRelation || self.layoutRelation == relation && [attribute isKindOfClass:NSValue.class], @"Redefinition of constraint relation");
+            self.layoutRelation = relation;
+            self.secondViewAttribute = attribute;
+            return self;
+        }
+    };
+}
+
+#pragma mark - Semantic properties
+
+- (MASConstraint *)with {
+    return self;
+}
+
+- (MASConstraint *)and {
+    return self;
+}
+
+#pragma mark - attribute chaining
+
+- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
+    NSAssert(!self.hasLayoutRelation, @"Attributes should be chained before defining the constraint relation");
+
+    return [self.delegate constraint:self addConstraintWithLayoutAttribute:layoutAttribute];
+}
+
+#pragma mark - Animator proxy
+
+#if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV)
+
+- (MASConstraint *)animator {
+    self.useAnimator = YES;
+    return self;
+}
+
+#endif
+
+#pragma mark - debug helpers
+
+- (MASConstraint * (^)(id))key {
+    return ^id(id key) {
+        self.mas_key = key;
+        return self;
+    };
+}
+
+#pragma mark - NSLayoutConstraint constant setters
+
+- (void)setInsets:(MASEdgeInsets)insets {
+    NSLayoutAttribute layoutAttribute = self.firstViewAttribute.layoutAttribute;
+    switch (layoutAttribute) {
+        case NSLayoutAttributeLeft:
+        case NSLayoutAttributeLeading:
+            self.layoutConstant = insets.left;
+            break;
+        case NSLayoutAttributeTop:
+            self.layoutConstant = insets.top;
+            break;
+        case NSLayoutAttributeBottom:
+            self.layoutConstant = -insets.bottom;
+            break;
+        case NSLayoutAttributeRight:
+        case NSLayoutAttributeTrailing:
+            self.layoutConstant = -insets.right;
+            break;
+        default:
+            break;
+    }
+}
+
+- (void)setInset:(CGFloat)inset {
+    [self setInsets:(MASEdgeInsets){.top = inset, .left = inset, .bottom = inset, .right = inset}];
+}
+
+- (void)setOffset:(CGFloat)offset {
+    self.layoutConstant = offset;
+}
+
+- (void)setSizeOffset:(CGSize)sizeOffset {
+    NSLayoutAttribute layoutAttribute = self.firstViewAttribute.layoutAttribute;
+    switch (layoutAttribute) {
+        case NSLayoutAttributeWidth:
+            self.layoutConstant = sizeOffset.width;
+            break;
+        case NSLayoutAttributeHeight:
+            self.layoutConstant = sizeOffset.height;
+            break;
+        default:
+            break;
+    }
+}
+
+- (void)setCenterOffset:(CGPoint)centerOffset {
+    NSLayoutAttribute layoutAttribute = self.firstViewAttribute.layoutAttribute;
+    switch (layoutAttribute) {
+        case NSLayoutAttributeCenterX:
+            self.layoutConstant = centerOffset.x;
+            break;
+        case NSLayoutAttributeCenterY:
+            self.layoutConstant = centerOffset.y;
+            break;
+        default:
+            break;
+    }
+}
+
+#pragma mark - MASConstraint
+
+- (void)activate {
+    [self install];
+}
+
+- (void)deactivate {
+    [self uninstall];
+}
+
+- (void)install {
+    if (self.hasBeenInstalled) {
+        return;
+    }
+    
+    if ([self supportsActiveProperty] && self.layoutConstraint) {
+        self.layoutConstraint.active = YES;
+        [self.firstViewAttribute.view.mas_installedConstraints addObject:self];
+        return;
+    }
+    
+    MAS_VIEW *firstLayoutItem = self.firstViewAttribute.item;
+    NSLayoutAttribute firstLayoutAttribute = self.firstViewAttribute.layoutAttribute;
+    MAS_VIEW *secondLayoutItem = self.secondViewAttribute.item;
+    NSLayoutAttribute secondLayoutAttribute = self.secondViewAttribute.layoutAttribute;
+
+    // alignment attributes must have a secondViewAttribute
+    // therefore we assume that is refering to superview
+    // eg make.left.equalTo(@10)
+    if (!self.firstViewAttribute.isSizeAttribute && !self.secondViewAttribute) {
+        secondLayoutItem = self.firstViewAttribute.view.superview;
+        secondLayoutAttribute = firstLayoutAttribute;
+    }
+    
+    MASLayoutConstraint *layoutConstraint
+        = [MASLayoutConstraint constraintWithItem:firstLayoutItem
+                                        attribute:firstLayoutAttribute
+                                        relatedBy:self.layoutRelation
+                                           toItem:secondLayoutItem
+                                        attribute:secondLayoutAttribute
+                                       multiplier:self.layoutMultiplier
+                                         constant:self.layoutConstant];
+    
+    layoutConstraint.priority = self.layoutPriority;
+    layoutConstraint.mas_key = self.mas_key;
+    
+    if (self.secondViewAttribute.view) {
+        MAS_VIEW *closestCommonSuperview = [self.firstViewAttribute.view mas_closestCommonSuperview:self.secondViewAttribute.view];
+        NSAssert(closestCommonSuperview,
+                 @"couldn't find a common superview for %@ and %@",
+                 self.firstViewAttribute.view, self.secondViewAttribute.view);
+        self.installedView = closestCommonSuperview;
+    } else if (self.firstViewAttribute.isSizeAttribute) {
+        self.installedView = self.firstViewAttribute.view;
+    } else {
+        self.installedView = self.firstViewAttribute.view.superview;
+    }
+
+
+    MASLayoutConstraint *existingConstraint = nil;
+    if (self.updateExisting) {
+        existingConstraint = [self layoutConstraintSimilarTo:layoutConstraint];
+    }
+    if (existingConstraint) {
+        // just update the constant
+        existingConstraint.constant = layoutConstraint.constant;
+        self.layoutConstraint = existingConstraint;
+    } else {
+        [self.installedView addConstraint:layoutConstraint];
+        self.layoutConstraint = layoutConstraint;
+        [firstLayoutItem.mas_installedConstraints addObject:self];
+    }
+}
+
+- (MASLayoutConstraint *)layoutConstraintSimilarTo:(MASLayoutConstraint *)layoutConstraint {
+    // check if any constraints are the same apart from the only mutable property constant
+
+    // go through constraints in reverse as we do not want to match auto-resizing or interface builder constraints
+    // and they are likely to be added first.
+    for (NSLayoutConstraint *existingConstraint in self.installedView.constraints.reverseObjectEnumerator) {
+        if (![existingConstraint isKindOfClass:MASLayoutConstraint.class]) continue;
+        if (existingConstraint.firstItem != layoutConstraint.firstItem) continue;
+        if (existingConstraint.secondItem != layoutConstraint.secondItem) continue;
+        if (existingConstraint.firstAttribute != layoutConstraint.firstAttribute) continue;
+        if (existingConstraint.secondAttribute != layoutConstraint.secondAttribute) continue;
+        if (existingConstraint.relation != layoutConstraint.relation) continue;
+        if (existingConstraint.multiplier != layoutConstraint.multiplier) continue;
+        if (existingConstraint.priority != layoutConstraint.priority) continue;
+
+        return (id)existingConstraint;
+    }
+    return nil;
+}
+
+- (void)uninstall {
+    if ([self supportsActiveProperty]) {
+        self.layoutConstraint.active = NO;
+        [self.firstViewAttribute.view.mas_installedConstraints removeObject:self];
+        return;
+    }
+    
+    [self.installedView removeConstraint:self.layoutConstraint];
+    self.layoutConstraint = nil;
+    self.installedView = nil;
+    
+    [self.firstViewAttribute.view.mas_installedConstraints removeObject:self];
+}
+
+@end

+ 29 - 0
PDFViewer/Masonry/Masonry.h

@@ -0,0 +1,29 @@
+//
+//  Masonry.h
+//  Masonry
+//
+//  Created by Jonas Budelmann on 20/07/13.
+//  Copyright (c) 2013 cloudling. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+//! Project version number for Masonry.
+FOUNDATION_EXPORT double MasonryVersionNumber;
+
+//! Project version string for Masonry.
+FOUNDATION_EXPORT const unsigned char MasonryVersionString[];
+
+#import "MASUtilities.h"
+#import "View+MASAdditions.h"
+#import "View+MASShorthandAdditions.h"
+#import "ViewController+MASAdditions.h"
+#import "NSArray+MASAdditions.h"
+#import "NSArray+MASShorthandAdditions.h"
+#import "MASConstraint.h"
+#import "MASCompositeConstraint.h"
+#import "MASViewAttribute.h"
+#import "MASViewConstraint.h"
+#import "MASConstraintMaker.h"
+#import "MASLayoutConstraint.h"
+#import "NSLayoutConstraint+MASDebugAdditions.h"

+ 72 - 0
PDFViewer/Masonry/NSArray+MASAdditions.h

@@ -0,0 +1,72 @@
+//
+//  NSArray+MASAdditions.h
+//
+//
+//  Created by Daniel Hammond on 11/26/13.
+//
+//
+
+#import "MASUtilities.h"
+#import "MASConstraintMaker.h"
+#import "MASViewAttribute.h"
+
+typedef NS_ENUM(NSUInteger, MASAxisType) {
+    MASAxisTypeHorizontal,
+    MASAxisTypeVertical
+};
+
+@interface NSArray (MASAdditions)
+
+/**
+ *  Creates a MASConstraintMaker with each view in the callee.
+ *  Any constraints defined are added to the view or the appropriate superview once the block has finished executing on each view
+ *
+ *  @param block scope within which you can build up the constraints which you wish to apply to each view.
+ *
+ *  @return Array of created MASConstraints
+ */
+- (NSArray *)mas_makeConstraints:(void (NS_NOESCAPE ^)(MASConstraintMaker *make))block;
+
+/**
+ *  Creates a MASConstraintMaker with each view in the callee.
+ *  Any constraints defined are added to each view or the appropriate superview once the block has finished executing on each view.
+ *  If an existing constraint exists then it will be updated instead.
+ *
+ *  @param block scope within which you can build up the constraints which you wish to apply to each view.
+ *
+ *  @return Array of created/updated MASConstraints
+ */
+- (NSArray *)mas_updateConstraints:(void (NS_NOESCAPE ^)(MASConstraintMaker *make))block;
+
+/**
+ *  Creates a MASConstraintMaker with each view in the callee.
+ *  Any constraints defined are added to each view or the appropriate superview once the block has finished executing on each view.
+ *  All constraints previously installed for the views will be removed.
+ *
+ *  @param block scope within which you can build up the constraints which you wish to apply to each view.
+ *
+ *  @return Array of created/updated MASConstraints
+ */
+- (NSArray *)mas_remakeConstraints:(void (NS_NOESCAPE ^)(MASConstraintMaker *make))block;
+
+/**
+ *  distribute with fixed spacing
+ *
+ *  @param axisType     which axis to distribute items along
+ *  @param fixedSpacing the spacing between each item
+ *  @param leadSpacing  the spacing before the first item and the container
+ *  @param tailSpacing  the spacing after the last item and the container
+ */
+- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)fixedSpacing leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing;
+
+/**
+ *  distribute with fixed item size
+ *
+ *  @param axisType        which axis to distribute items along
+ *  @param fixedItemLength the fixed length of each item
+ *  @param leadSpacing     the spacing before the first item and the container
+ *  @param tailSpacing     the spacing after the last item and the container
+ */
+- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)fixedItemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing;
+
+@end

+ 162 - 0
PDFViewer/Masonry/NSArray+MASAdditions.m

@@ -0,0 +1,162 @@
+//
+//  NSArray+MASAdditions.m
+//  
+//
+//  Created by Daniel Hammond on 11/26/13.
+//
+//
+
+#import "NSArray+MASAdditions.h"
+#import "View+MASAdditions.h"
+
+@implementation NSArray (MASAdditions)
+
+- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block {
+    NSMutableArray *constraints = [NSMutableArray array];
+    for (MAS_VIEW *view in self) {
+        NSAssert([view isKindOfClass:[MAS_VIEW class]], @"All objects in the array must be views");
+        [constraints addObjectsFromArray:[view mas_makeConstraints:block]];
+    }
+    return constraints;
+}
+
+- (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block {
+    NSMutableArray *constraints = [NSMutableArray array];
+    for (MAS_VIEW *view in self) {
+        NSAssert([view isKindOfClass:[MAS_VIEW class]], @"All objects in the array must be views");
+        [constraints addObjectsFromArray:[view mas_updateConstraints:block]];
+    }
+    return constraints;
+}
+
+- (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block {
+    NSMutableArray *constraints = [NSMutableArray array];
+    for (MAS_VIEW *view in self) {
+        NSAssert([view isKindOfClass:[MAS_VIEW class]], @"All objects in the array must be views");
+        [constraints addObjectsFromArray:[view mas_remakeConstraints:block]];
+    }
+    return constraints;
+}
+
+- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)fixedSpacing leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing {
+    if (self.count < 2) {
+        NSAssert(self.count>1,@"views to distribute need to bigger than one");
+        return;
+    }
+    
+    MAS_VIEW *tempSuperView = [self mas_commonSuperviewOfViews];
+    if (axisType == MASAxisTypeHorizontal) {
+        MAS_VIEW *prev;
+        for (int i = 0; i < self.count; i++) {
+            MAS_VIEW *v = self[i];
+            [v mas_makeConstraints:^(MASConstraintMaker *make) {
+                if (prev) {
+                    make.width.equalTo(prev);
+                    make.left.equalTo(prev.mas_right).offset(fixedSpacing);
+                    if (i == self.count - 1) {//last one
+                        make.right.equalTo(tempSuperView).offset(-tailSpacing);
+                    }
+                }
+                else {//first one
+                    make.left.equalTo(tempSuperView).offset(leadSpacing);
+                }
+                
+            }];
+            prev = v;
+        }
+    }
+    else {
+        MAS_VIEW *prev;
+        for (int i = 0; i < self.count; i++) {
+            MAS_VIEW *v = self[i];
+            [v mas_makeConstraints:^(MASConstraintMaker *make) {
+                if (prev) {
+                    make.height.equalTo(prev);
+                    make.top.equalTo(prev.mas_bottom).offset(fixedSpacing);
+                    if (i == self.count - 1) {//last one
+                        make.bottom.equalTo(tempSuperView).offset(-tailSpacing);
+                    }                    
+                }
+                else {//first one
+                    make.top.equalTo(tempSuperView).offset(leadSpacing);
+                }
+                
+            }];
+            prev = v;
+        }
+    }
+}
+
+- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)fixedItemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing {
+    if (self.count < 2) {
+        NSAssert(self.count>1,@"views to distribute need to bigger than one");
+        return;
+    }
+    
+    MAS_VIEW *tempSuperView = [self mas_commonSuperviewOfViews];
+    if (axisType == MASAxisTypeHorizontal) {
+        MAS_VIEW *prev;
+        for (int i = 0; i < self.count; i++) {
+            MAS_VIEW *v = self[i];
+            [v mas_makeConstraints:^(MASConstraintMaker *make) {
+                make.width.equalTo(@(fixedItemLength));
+                if (prev) {
+                    if (i == self.count - 1) {//last one
+                        make.right.equalTo(tempSuperView).offset(-tailSpacing);
+                    }
+                    else {
+                        CGFloat offset = (1-(i/((CGFloat)self.count-1)))*(fixedItemLength+leadSpacing)-i*tailSpacing/(((CGFloat)self.count-1));
+                        make.right.equalTo(tempSuperView).multipliedBy(i/((CGFloat)self.count-1)).with.offset(offset);
+                    }
+                }
+                else {//first one
+                    make.left.equalTo(tempSuperView).offset(leadSpacing);
+                }
+            }];
+            prev = v;
+        }
+    }
+    else {
+        MAS_VIEW *prev;
+        for (int i = 0; i < self.count; i++) {
+            MAS_VIEW *v = self[i];
+            [v mas_makeConstraints:^(MASConstraintMaker *make) {
+                make.height.equalTo(@(fixedItemLength));
+                if (prev) {
+                    if (i == self.count - 1) {//last one
+                        make.bottom.equalTo(tempSuperView).offset(-tailSpacing);
+                    }
+                    else {
+                        CGFloat offset = (1-(i/((CGFloat)self.count-1)))*(fixedItemLength+leadSpacing)-i*tailSpacing/(((CGFloat)self.count-1));
+                        make.bottom.equalTo(tempSuperView).multipliedBy(i/((CGFloat)self.count-1)).with.offset(offset);
+                    }
+                }
+                else {//first one
+                    make.top.equalTo(tempSuperView).offset(leadSpacing);
+                }
+            }];
+            prev = v;
+        }
+    }
+}
+
+- (MAS_VIEW *)mas_commonSuperviewOfViews
+{
+    MAS_VIEW *commonSuperview = nil;
+    MAS_VIEW *previousView = nil;
+    for (id object in self) {
+        if ([object isKindOfClass:[MAS_VIEW class]]) {
+            MAS_VIEW *view = (MAS_VIEW *)object;
+            if (previousView) {
+                commonSuperview = [view mas_closestCommonSuperview:commonSuperview];
+            } else {
+                commonSuperview = view;
+            }
+            previousView = view;
+        }
+    }
+    NSAssert(commonSuperview, @"Can't constrain views that do not share a common superview. Make sure that all the views in this array have been added into the same view hierarchy.");
+    return commonSuperview;
+}
+
+@end

+ 41 - 0
PDFViewer/Masonry/NSArray+MASShorthandAdditions.h

@@ -0,0 +1,41 @@
+//
+//  NSArray+MASShorthandAdditions.h
+//  Masonry
+//
+//  Created by Jonas Budelmann on 22/07/13.
+//  Copyright (c) 2013 Jonas Budelmann. All rights reserved.
+//
+
+#import "NSArray+MASAdditions.h"
+
+#ifdef MAS_SHORTHAND
+
+/**
+ *	Shorthand array additions without the 'mas_' prefixes,
+ *  only enabled if MAS_SHORTHAND is defined
+ */
+@interface NSArray (MASShorthandAdditions)
+
+- (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *make))block;
+- (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *make))block;
+- (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *make))block;
+
+@end
+
+@implementation NSArray (MASShorthandAdditions)
+
+- (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *))block {
+    return [self mas_makeConstraints:block];
+}
+
+- (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *))block {
+    return [self mas_updateConstraints:block];
+}
+
+- (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *))block {
+    return [self mas_remakeConstraints:block];
+}
+
+@end
+
+#endif

+ 16 - 0
PDFViewer/Masonry/NSLayoutConstraint+MASDebugAdditions.h

@@ -0,0 +1,16 @@
+//
+//  NSLayoutConstraint+MASDebugAdditions.h
+//  Masonry
+//
+//  Created by Jonas Budelmann on 3/08/13.
+//  Copyright (c) 2013 Jonas Budelmann. All rights reserved.
+//
+
+#import "MASUtilities.h"
+
+/**
+ *	makes debug and log output of NSLayoutConstraints more readable
+ */
+@interface NSLayoutConstraint (MASDebugAdditions)
+
+@end

+ 143 - 0
PDFViewer/Masonry/NSLayoutConstraint+MASDebugAdditions.m

@@ -0,0 +1,143 @@
+//
+//  NSLayoutConstraint+MASDebugAdditions.m
+//  Masonry
+//
+//  Created by Jonas Budelmann on 3/08/13.
+//  Copyright (c) 2013 Jonas Budelmann. All rights reserved.
+//
+
+#import "NSLayoutConstraint+MASDebugAdditions.h"
+#import "MASConstraint.h"
+#import "MASLayoutConstraint.h"
+
+@implementation NSLayoutConstraint (MASDebugAdditions)
+
+#pragma mark - description maps
+
++ (NSDictionary *)layoutRelationDescriptionsByValue {
+    static dispatch_once_t once;
+    static NSDictionary *descriptionMap;
+    dispatch_once(&once, ^{
+        descriptionMap = @{
+            @(NSLayoutRelationEqual)                : @"==",
+            @(NSLayoutRelationGreaterThanOrEqual)   : @">=",
+            @(NSLayoutRelationLessThanOrEqual)      : @"<=",
+        };
+    });
+    return descriptionMap;
+}
+
++ (NSDictionary *)layoutAttributeDescriptionsByValue {
+    static dispatch_once_t once;
+    static NSDictionary *descriptionMap;
+    dispatch_once(&once, ^{
+        descriptionMap = @{
+            @(NSLayoutAttributeTop)      : @"top",
+            @(NSLayoutAttributeLeft)     : @"left",
+            @(NSLayoutAttributeBottom)   : @"bottom",
+            @(NSLayoutAttributeRight)    : @"right",
+            @(NSLayoutAttributeLeading)  : @"leading",
+            @(NSLayoutAttributeTrailing) : @"trailing",
+            @(NSLayoutAttributeWidth)    : @"width",
+            @(NSLayoutAttributeHeight)   : @"height",
+            @(NSLayoutAttributeCenterX)  : @"centerX",
+            @(NSLayoutAttributeCenterY)  : @"centerY",
+            @(NSLayoutAttributeBaseline) : @"baseline",
+            @(NSLayoutAttributeFirstBaseline) : @"firstBaseline",
+            @(NSLayoutAttributeLastBaseline) : @"lastBaseline",
+
+#if TARGET_OS_IPHONE || TARGET_OS_TV
+            @(NSLayoutAttributeLeftMargin)           : @"leftMargin",
+            @(NSLayoutAttributeRightMargin)          : @"rightMargin",
+            @(NSLayoutAttributeTopMargin)            : @"topMargin",
+            @(NSLayoutAttributeBottomMargin)         : @"bottomMargin",
+            @(NSLayoutAttributeLeadingMargin)        : @"leadingMargin",
+            @(NSLayoutAttributeTrailingMargin)       : @"trailingMargin",
+            @(NSLayoutAttributeCenterXWithinMargins) : @"centerXWithinMargins",
+            @(NSLayoutAttributeCenterYWithinMargins) : @"centerYWithinMargins",
+#endif
+            
+        };
+    
+    });
+    return descriptionMap;
+}
+
+
++ (NSDictionary *)layoutPriorityDescriptionsByValue {
+    static dispatch_once_t once;
+    static NSDictionary *descriptionMap;
+    dispatch_once(&once, ^{
+#if TARGET_OS_IPHONE || TARGET_OS_TV
+        descriptionMap = @{
+            @(MASLayoutPriorityDefaultHigh)      : @"high",
+            @(MASLayoutPriorityDefaultLow)       : @"low",
+            @(MASLayoutPriorityDefaultMedium)    : @"medium",
+            @(MASLayoutPriorityRequired)         : @"required",
+            @(MASLayoutPriorityFittingSizeLevel) : @"fitting size",
+        };
+#elif TARGET_OS_MAC
+        descriptionMap = @{
+            @(MASLayoutPriorityDefaultHigh)                 : @"high",
+            @(MASLayoutPriorityDragThatCanResizeWindow)     : @"drag can resize window",
+            @(MASLayoutPriorityDefaultMedium)               : @"medium",
+            @(MASLayoutPriorityWindowSizeStayPut)           : @"window size stay put",
+            @(MASLayoutPriorityDragThatCannotResizeWindow)  : @"drag cannot resize window",
+            @(MASLayoutPriorityDefaultLow)                  : @"low",
+            @(MASLayoutPriorityFittingSizeCompression)      : @"fitting size",
+            @(MASLayoutPriorityRequired)                    : @"required",
+        };
+#endif
+    });
+    return descriptionMap;
+}
+
+#pragma mark - description override
+
++ (NSString *)descriptionForObject:(id)obj {
+    if ([obj respondsToSelector:@selector(mas_key)] && [obj mas_key]) {
+        return [NSString stringWithFormat:@"%@:%@", [obj class], [obj mas_key]];
+    }
+    return [NSString stringWithFormat:@"%@:%p", [obj class], obj];
+}
+
+- (NSString *)description {
+    NSMutableString *description = [[NSMutableString alloc] initWithString:@"<"];
+
+    [description appendString:[self.class descriptionForObject:self]];
+
+    [description appendFormat:@" %@", [self.class descriptionForObject:self.firstItem]];
+    if (self.firstAttribute != NSLayoutAttributeNotAnAttribute) {
+        [description appendFormat:@".%@", self.class.layoutAttributeDescriptionsByValue[@(self.firstAttribute)]];
+    }
+
+    [description appendFormat:@" %@", self.class.layoutRelationDescriptionsByValue[@(self.relation)]];
+
+    if (self.secondItem) {
+        [description appendFormat:@" %@", [self.class descriptionForObject:self.secondItem]];
+    }
+    if (self.secondAttribute != NSLayoutAttributeNotAnAttribute) {
+        [description appendFormat:@".%@", self.class.layoutAttributeDescriptionsByValue[@(self.secondAttribute)]];
+    }
+    
+    if (self.multiplier != 1) {
+        [description appendFormat:@" * %g", self.multiplier];
+    }
+    
+    if (self.secondAttribute == NSLayoutAttributeNotAnAttribute) {
+        [description appendFormat:@" %g", self.constant];
+    } else {
+        if (self.constant) {
+            [description appendFormat:@" %@ %g", (self.constant < 0 ? @"-" : @"+"), ABS(self.constant)];
+        }
+    }
+
+    if (self.priority != MASLayoutPriorityRequired) {
+        [description appendFormat:@" ^%@", self.class.layoutPriorityDescriptionsByValue[@(self.priority)] ?: [NSNumber numberWithDouble:self.priority]];
+    }
+
+    [description appendString:@">"];
+    return description;
+}
+
+@end

+ 109 - 0
PDFViewer/Masonry/View+MASAdditions.h

@@ -0,0 +1,109 @@
+//
+//  UIView+MASAdditions.h
+//  Masonry
+//
+//  Created by Jonas Budelmann on 20/07/13.
+//  Copyright (c) 2013 cloudling. All rights reserved.
+//
+
+#import "MASUtilities.h"
+#import "MASConstraintMaker.h"
+#import "MASViewAttribute.h"
+
+/**
+ *	Provides constraint maker block
+ *  and convience methods for creating MASViewAttribute which are view + NSLayoutAttribute pairs
+ */
+@interface MAS_VIEW (MASAdditions)
+
+/**
+ *	following properties return a new MASViewAttribute with current view and appropriate NSLayoutAttribute
+ */
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_left;
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_top;
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_right;
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_bottom;
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_leading;
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_trailing;
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_width;
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_height;
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_centerX;
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_centerY;
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_baseline;
+@property (nonatomic, strong, readonly) MASViewAttribute *(^mas_attribute)(NSLayoutAttribute attr);
+
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_firstBaseline;
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_lastBaseline;
+
+#if TARGET_OS_IPHONE || TARGET_OS_TV
+
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_leftMargin;
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_rightMargin;
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_topMargin;
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomMargin;
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_leadingMargin;
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_trailingMargin;
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_centerXWithinMargins;
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_centerYWithinMargins;
+
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuide NS_AVAILABLE_IOS(11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideLeading NS_AVAILABLE_IOS(11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideTrailing NS_AVAILABLE_IOS(11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideLeft NS_AVAILABLE_IOS(11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideRight NS_AVAILABLE_IOS(11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideTop NS_AVAILABLE_IOS(11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideBottom NS_AVAILABLE_IOS(11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideWidth NS_AVAILABLE_IOS(11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideHeight NS_AVAILABLE_IOS(11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideCenterX NS_AVAILABLE_IOS(11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideCenterY NS_AVAILABLE_IOS(11.0);
+
+#endif
+
+/**
+ *	a key to associate with this view
+ */
+@property (nonatomic, strong) id mas_key;
+
+/**
+ *	Finds the closest common superview between this view and another view
+ *
+ *	@param	view	other view
+ *
+ *	@return	returns nil if common superview could not be found
+ */
+- (instancetype)mas_closestCommonSuperview:(MAS_VIEW *)view;
+
+/**
+ *  Creates a MASConstraintMaker with the callee view.
+ *  Any constraints defined are added to the view or the appropriate superview once the block has finished executing
+ *
+ *  @param block scope within which you can build up the constraints which you wish to apply to the view.
+ *
+ *  @return Array of created MASConstraints
+ */
+- (NSArray *)mas_makeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;
+
+/**
+ *  Creates a MASConstraintMaker with the callee view.
+ *  Any constraints defined are added to the view or the appropriate superview once the block has finished executing.
+ *  If an existing constraint exists then it will be updated instead.
+ *
+ *  @param block scope within which you can build up the constraints which you wish to apply to the view.
+ *
+ *  @return Array of created/updated MASConstraints
+ */
+- (NSArray *)mas_updateConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;
+
+/**
+ *  Creates a MASConstraintMaker with the callee view.
+ *  Any constraints defined are added to the view or the appropriate superview once the block has finished executing.
+ *  All constraints previously installed for the view will be removed.
+ *
+ *  @param block scope within which you can build up the constraints which you wish to apply to the view.
+ *
+ *  @return Array of created/updated MASConstraints
+ */
+- (NSArray *)mas_remakeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;
+
+@end

+ 206 - 0
PDFViewer/Masonry/View+MASAdditions.m

@@ -0,0 +1,206 @@
+//
+//  UIView+MASAdditions.m
+//  Masonry
+//
+//  Created by Jonas Budelmann on 20/07/13.
+//  Copyright (c) 2013 cloudling. All rights reserved.
+//
+
+#import "View+MASAdditions.h"
+#import <objc/runtime.h>
+
+@implementation MAS_VIEW (MASAdditions)
+
+- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *))block {
+    self.translatesAutoresizingMaskIntoConstraints = NO;
+    MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self];
+    block(constraintMaker);
+    return [constraintMaker install];
+}
+
+- (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *))block {
+    self.translatesAutoresizingMaskIntoConstraints = NO;
+    MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self];
+    constraintMaker.updateExisting = YES;
+    block(constraintMaker);
+    return [constraintMaker install];
+}
+
+- (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block {
+    self.translatesAutoresizingMaskIntoConstraints = NO;
+    MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self];
+    constraintMaker.removeExisting = YES;
+    block(constraintMaker);
+    return [constraintMaker install];
+}
+
+#pragma mark - NSLayoutAttribute properties
+
+- (MASViewAttribute *)mas_left {
+    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeft];
+}
+
+- (MASViewAttribute *)mas_top {
+    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTop];
+}
+
+- (MASViewAttribute *)mas_right {
+    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeRight];
+}
+
+- (MASViewAttribute *)mas_bottom {
+    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeBottom];
+}
+
+- (MASViewAttribute *)mas_leading {
+    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeading];
+}
+
+- (MASViewAttribute *)mas_trailing {
+    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTrailing];
+}
+
+- (MASViewAttribute *)mas_width {
+    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeWidth];
+}
+
+- (MASViewAttribute *)mas_height {
+    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeHeight];
+}
+
+- (MASViewAttribute *)mas_centerX {
+    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterX];
+}
+
+- (MASViewAttribute *)mas_centerY {
+    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterY];
+}
+
+- (MASViewAttribute *)mas_baseline {
+    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeBaseline];
+}
+
+- (MASViewAttribute *(^)(NSLayoutAttribute))mas_attribute
+{
+    return ^(NSLayoutAttribute attr) {
+        return [[MASViewAttribute alloc] initWithView:self layoutAttribute:attr];
+    };
+}
+
+- (MASViewAttribute *)mas_firstBaseline {
+    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeFirstBaseline];
+}
+- (MASViewAttribute *)mas_lastBaseline {
+    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLastBaseline];
+}
+
+#if TARGET_OS_IPHONE || TARGET_OS_TV
+
+- (MASViewAttribute *)mas_leftMargin {
+    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeftMargin];
+}
+
+- (MASViewAttribute *)mas_rightMargin {
+    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeRightMargin];
+}
+
+- (MASViewAttribute *)mas_topMargin {
+    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTopMargin];
+}
+
+- (MASViewAttribute *)mas_bottomMargin {
+    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeBottomMargin];
+}
+
+- (MASViewAttribute *)mas_leadingMargin {
+    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeadingMargin];
+}
+
+- (MASViewAttribute *)mas_trailingMargin {
+    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTrailingMargin];
+}
+
+- (MASViewAttribute *)mas_centerXWithinMargins {
+    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterXWithinMargins];
+}
+
+- (MASViewAttribute *)mas_centerYWithinMargins {
+    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterYWithinMargins];
+}
+
+- (MASViewAttribute *)mas_safeAreaLayoutGuide {
+    return [[MASViewAttribute alloc] initWithView:self item:self.safeAreaLayoutGuide layoutAttribute:NSLayoutAttributeNotAnAttribute];
+}
+
+- (MASViewAttribute *)mas_safeAreaLayoutGuideLeading {
+    return [[MASViewAttribute alloc] initWithView:self item:self.safeAreaLayoutGuide layoutAttribute:NSLayoutAttributeLeading];
+}
+
+- (MASViewAttribute *)mas_safeAreaLayoutGuideTrailing {
+    return [[MASViewAttribute alloc] initWithView:self item:self.safeAreaLayoutGuide layoutAttribute:NSLayoutAttributeTrailing];
+}
+
+- (MASViewAttribute *)mas_safeAreaLayoutGuideLeft {
+    return [[MASViewAttribute alloc] initWithView:self item:self.safeAreaLayoutGuide layoutAttribute:NSLayoutAttributeLeft];
+}
+
+- (MASViewAttribute *)mas_safeAreaLayoutGuideRight {
+    return [[MASViewAttribute alloc] initWithView:self item:self.safeAreaLayoutGuide layoutAttribute:NSLayoutAttributeRight];
+}
+
+- (MASViewAttribute *)mas_safeAreaLayoutGuideTop {
+    return [[MASViewAttribute alloc] initWithView:self item:self.safeAreaLayoutGuide layoutAttribute:NSLayoutAttributeTop];
+}
+
+- (MASViewAttribute *)mas_safeAreaLayoutGuideBottom {
+    return [[MASViewAttribute alloc] initWithView:self item:self.safeAreaLayoutGuide layoutAttribute:NSLayoutAttributeBottom];
+}
+
+- (MASViewAttribute *)mas_safeAreaLayoutGuideWidth {
+    return [[MASViewAttribute alloc] initWithView:self item:self.safeAreaLayoutGuide layoutAttribute:NSLayoutAttributeWidth];
+}
+
+- (MASViewAttribute *)mas_safeAreaLayoutGuideHeight {
+    return [[MASViewAttribute alloc] initWithView:self item:self.safeAreaLayoutGuide layoutAttribute:NSLayoutAttributeHeight];
+}
+
+- (MASViewAttribute *)mas_safeAreaLayoutGuideCenterX {
+    return [[MASViewAttribute alloc] initWithView:self item:self.safeAreaLayoutGuide layoutAttribute:NSLayoutAttributeCenterX];
+}
+
+- (MASViewAttribute *)mas_safeAreaLayoutGuideCenterY {
+    return [[MASViewAttribute alloc] initWithView:self item:self.safeAreaLayoutGuide layoutAttribute:NSLayoutAttributeCenterY];
+}
+
+#endif
+
+#pragma mark - associated properties
+
+- (id)mas_key {
+    return objc_getAssociatedObject(self, @selector(mas_key));
+}
+
+- (void)setMas_key:(id)key {
+    objc_setAssociatedObject(self, @selector(mas_key), key, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+}
+
+#pragma mark - heirachy
+
+- (instancetype)mas_closestCommonSuperview:(MAS_VIEW *)view {
+    MAS_VIEW *closestCommonSuperview = nil;
+
+    MAS_VIEW *secondViewSuperview = view;
+    while (!closestCommonSuperview && secondViewSuperview) {
+        MAS_VIEW *firstViewSuperview = self;
+        while (!closestCommonSuperview && firstViewSuperview) {
+            if (secondViewSuperview == firstViewSuperview) {
+                closestCommonSuperview = secondViewSuperview;
+            }
+            firstViewSuperview = firstViewSuperview.superview;
+        }
+        secondViewSuperview = secondViewSuperview.superview;
+    }
+    return closestCommonSuperview;
+}
+
+@end

+ 138 - 0
PDFViewer/Masonry/View+MASShorthandAdditions.h

@@ -0,0 +1,138 @@
+//
+//  UIView+MASShorthandAdditions.h
+//  Masonry
+//
+//  Created by Jonas Budelmann on 22/07/13.
+//  Copyright (c) 2013 Jonas Budelmann. All rights reserved.
+//
+
+#import "View+MASAdditions.h"
+
+#ifdef MAS_SHORTHAND
+
+/**
+ *	Shorthand view additions without the 'mas_' prefixes,
+ *  only enabled if MAS_SHORTHAND is defined
+ */
+@interface MAS_VIEW (MASShorthandAdditions)
+
+@property (nonatomic, strong, readonly) MASViewAttribute *left;
+@property (nonatomic, strong, readonly) MASViewAttribute *top;
+@property (nonatomic, strong, readonly) MASViewAttribute *right;
+@property (nonatomic, strong, readonly) MASViewAttribute *bottom;
+@property (nonatomic, strong, readonly) MASViewAttribute *leading;
+@property (nonatomic, strong, readonly) MASViewAttribute *trailing;
+@property (nonatomic, strong, readonly) MASViewAttribute *width;
+@property (nonatomic, strong, readonly) MASViewAttribute *height;
+@property (nonatomic, strong, readonly) MASViewAttribute *centerX;
+@property (nonatomic, strong, readonly) MASViewAttribute *centerY;
+@property (nonatomic, strong, readonly) MASViewAttribute *baseline;
+@property (nonatomic, strong, readonly) MASViewAttribute *(^attribute)(NSLayoutAttribute attr);
+
+@property (nonatomic, strong, readonly) MASViewAttribute *firstBaseline;
+@property (nonatomic, strong, readonly) MASViewAttribute *lastBaseline;
+
+#if TARGET_OS_IPHONE || TARGET_OS_TV
+
+@property (nonatomic, strong, readonly) MASViewAttribute *leftMargin;
+@property (nonatomic, strong, readonly) MASViewAttribute *rightMargin;
+@property (nonatomic, strong, readonly) MASViewAttribute *topMargin;
+@property (nonatomic, strong, readonly) MASViewAttribute *bottomMargin;
+@property (nonatomic, strong, readonly) MASViewAttribute *leadingMargin;
+@property (nonatomic, strong, readonly) MASViewAttribute *trailingMargin;
+@property (nonatomic, strong, readonly) MASViewAttribute *centerXWithinMargins;
+@property (nonatomic, strong, readonly) MASViewAttribute *centerYWithinMargins;
+
+#endif
+
+#if TARGET_OS_IPHONE || TARGET_OS_TV
+
+@property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideLeading NS_AVAILABLE_IOS(11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideTrailing NS_AVAILABLE_IOS(11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideLeft NS_AVAILABLE_IOS(11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideRight NS_AVAILABLE_IOS(11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideTop NS_AVAILABLE_IOS(11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideBottom NS_AVAILABLE_IOS(11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideWidth NS_AVAILABLE_IOS(11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideHeight NS_AVAILABLE_IOS(11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideCenterX NS_AVAILABLE_IOS(11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideCenterY NS_AVAILABLE_IOS(11.0);
+
+#endif
+
+- (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *make))block;
+- (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *make))block;
+- (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *make))block;
+
+@end
+
+#define MAS_ATTR_FORWARD(attr)  \
+- (MASViewAttribute *)attr {    \
+    return [self mas_##attr];   \
+}
+
+#define MAS_ATTR_FORWARD_AVAILABLE(attr, available)  \
+- (MASViewAttribute *)attr available {    \
+    return [self mas_##attr];   \
+}
+
+@implementation MAS_VIEW (MASShorthandAdditions)
+
+MAS_ATTR_FORWARD(top);
+MAS_ATTR_FORWARD(left);
+MAS_ATTR_FORWARD(bottom);
+MAS_ATTR_FORWARD(right);
+MAS_ATTR_FORWARD(leading);
+MAS_ATTR_FORWARD(trailing);
+MAS_ATTR_FORWARD(width);
+MAS_ATTR_FORWARD(height);
+MAS_ATTR_FORWARD(centerX);
+MAS_ATTR_FORWARD(centerY);
+MAS_ATTR_FORWARD(baseline);
+
+MAS_ATTR_FORWARD(firstBaseline);
+MAS_ATTR_FORWARD(lastBaseline);
+
+#if TARGET_OS_IPHONE || TARGET_OS_TV
+
+MAS_ATTR_FORWARD(leftMargin);
+MAS_ATTR_FORWARD(rightMargin);
+MAS_ATTR_FORWARD(topMargin);
+MAS_ATTR_FORWARD(bottomMargin);
+MAS_ATTR_FORWARD(leadingMargin);
+MAS_ATTR_FORWARD(trailingMargin);
+MAS_ATTR_FORWARD(centerXWithinMargins);
+MAS_ATTR_FORWARD(centerYWithinMargins);
+
+MAS_ATTR_FORWARD_AVAILABLE(safeAreaLayoutGuideLeading, NS_AVAILABLE_IOS(11.0));
+MAS_ATTR_FORWARD_AVAILABLE(safeAreaLayoutGuideTrailing, NS_AVAILABLE_IOS(11.0));
+MAS_ATTR_FORWARD_AVAILABLE(safeAreaLayoutGuideLeft, NS_AVAILABLE_IOS(11.0));
+MAS_ATTR_FORWARD_AVAILABLE(safeAreaLayoutGuideRight, NS_AVAILABLE_IOS(11.0));
+MAS_ATTR_FORWARD_AVAILABLE(safeAreaLayoutGuideTop, NS_AVAILABLE_IOS(11.0));
+MAS_ATTR_FORWARD_AVAILABLE(safeAreaLayoutGuideBottom, NS_AVAILABLE_IOS(11.0));
+MAS_ATTR_FORWARD_AVAILABLE(safeAreaLayoutGuideWidth, NS_AVAILABLE_IOS(11.0));
+MAS_ATTR_FORWARD_AVAILABLE(safeAreaLayoutGuideHeight, NS_AVAILABLE_IOS(11.0));
+MAS_ATTR_FORWARD_AVAILABLE(safeAreaLayoutGuideCenterX, NS_AVAILABLE_IOS(11.0));
+MAS_ATTR_FORWARD_AVAILABLE(safeAreaLayoutGuideCenterY, NS_AVAILABLE_IOS(11.0));
+
+#endif
+
+- (MASViewAttribute *(^)(NSLayoutAttribute))attribute {
+    return [self mas_attribute];
+}
+
+- (NSArray *)makeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *))block {
+    return [self mas_makeConstraints:block];
+}
+
+- (NSArray *)updateConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *))block {
+    return [self mas_updateConstraints:block];
+}
+
+- (NSArray *)remakeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *))block {
+    return [self mas_remakeConstraints:block];
+}
+
+@end
+
+#endif

+ 29 - 0
PDFViewer/Masonry/ViewController+MASAdditions.h

@@ -0,0 +1,29 @@
+//
+//  UIViewController+MASAdditions.h
+//  Masonry
+//
+//  Created by Craig Siemens on 2015-06-23.
+//
+//
+
+#import "MASUtilities.h"
+#import "MASConstraintMaker.h"
+#import "MASViewAttribute.h"
+
+#ifdef MAS_VIEW_CONTROLLER
+
+@interface MAS_VIEW_CONTROLLER (MASAdditions)
+
+/**
+ *	following properties return a new MASViewAttribute with appropriate UILayoutGuide and NSLayoutAttribute
+ */
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuide NS_DEPRECATED_IOS(8.0, 11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuide NS_DEPRECATED_IOS(8.0, 11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuideTop NS_DEPRECATED_IOS(8.0, 11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuideBottom NS_DEPRECATED_IOS(8.0, 11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuideTop NS_DEPRECATED_IOS(8.0, 11.0);
+@property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuideBottom NS_DEPRECATED_IOS(8.0, 11.0);
+
+@end
+
+#endif

+ 42 - 0
PDFViewer/Masonry/ViewController+MASAdditions.m

@@ -0,0 +1,42 @@
+//
+//  UIViewController+MASAdditions.m
+//  Masonry
+//
+//  Created by Craig Siemens on 2015-06-23.
+//
+//
+
+#import "ViewController+MASAdditions.h"
+
+#ifdef MAS_VIEW_CONTROLLER
+
+@implementation MAS_VIEW_CONTROLLER (MASAdditions)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+- (MASViewAttribute *)mas_topLayoutGuide {
+    return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeBottom];
+}
+- (MASViewAttribute *)mas_topLayoutGuideTop {
+    return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeTop];
+}
+- (MASViewAttribute *)mas_topLayoutGuideBottom {
+    return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeBottom];
+}
+
+- (MASViewAttribute *)mas_bottomLayoutGuide {
+    return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeTop];
+}
+- (MASViewAttribute *)mas_bottomLayoutGuideTop {
+    return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeTop];
+}
+- (MASViewAttribute *)mas_bottomLayoutGuideBottom {
+    return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeBottom];
+}
+
+#pragma clang diagnostic pop
+
+@end
+
+#endif

+ 3 - 5
PDFViewer/View/CPDFWatermarkView.h

@@ -1,17 +1,15 @@
 //
-//  CPDFWatermarkView.h
+//  CPDFImagePreview.h
 //  PDFViewer
 //
-//  Created by kdan on 2022/11/15.
+//  Created by kdan on 2022/11/18.
 //
 
 #import <UIKit/UIKit.h>
 
 NS_ASSUME_NONNULL_BEGIN
 
-@interface CPDFWatermarkView : UIView
-
-
+@interface CPDFImagePreview : UIView
 
 @end
 

+ 4 - 4
PDFViewer/View/CPDFWatermarkView.m

@@ -1,13 +1,13 @@
 //
-//  CPDFWatermarkView.m
+//  CPDFImagePreview.m
 //  PDFViewer
 //
-//  Created by kdan on 2022/11/15.
+//  Created by kdan on 2022/11/18.
 //
 
-#import "CPDFWatermarkView.h"
+#import "CPDFImagePreview.h"
 
-@implementation CPDFWatermarkView
+@implementation CPDFImagePreview
 
 /*
 // Only override drawRect: if you perform custom drawing.

+ 16 - 0
PDFViewer/View/CPDFImageView.h

@@ -0,0 +1,16 @@
+//
+//  CPDFImageView.h
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/16.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFImageView : UIView
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 14 - 0
PDFViewer/View/CPDFImageView.m

@@ -0,0 +1,14 @@
+//
+//  CPDFImageView.m
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/16.
+//
+
+#import "CPDFImageView.h"
+
+@implementation CPDFImageView
+
+
+
+@end

+ 22 - 0
PDFViewer/View/CPDFPageRangeDropDownList.h

@@ -0,0 +1,22 @@
+//
+//  CPDFPageRangeDropDownList.h
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/18.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFPageRangeDropDownList : UIView
+
+@property (nonatomic,retain)UITextField *textField;
+@property (nonatomic,retain)NSArray* list;
+@property (nonatomic,retain)UITableView* listView;
+@property (nonatomic,retain)UIColor *lineColor,*listBgColor;
+@property (nonatomic,assign)UITextBorderStyle borderStyle;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 13 - 0
PDFViewer/View/CPDFPageRangeDropDownList.m

@@ -0,0 +1,13 @@
+//
+//  CPDFPageRangeDropDownList.m
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/18.
+//
+
+#import "CPDFPageRangeDropDownList.h"
+
+@implementation CPDFPageRangeDropDownList
+
+
+@end

+ 19 - 0
PDFViewer/View/CPDFTextPreview.h

@@ -0,0 +1,19 @@
+//
+//  CPDFTextPreview.h
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/18.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFTextPreview : UIView
+
+@property (nonatomic,strong) UILabel *watermarkLabel;
+@property (nonatomic,strong) UIButton *rotationBtn;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 38 - 0
PDFViewer/View/CPDFTextPreview.m

@@ -0,0 +1,38 @@
+//
+//  CPDFTextPreview.m
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/18.
+//
+
+#import "CPDFTextPreview.h"
+
+@implementation CPDFTextPreview
+
+- (instancetype)initWithFrame:(CGRect)frame
+{
+    if (self = [super initWithFrame:frame]) {
+        _watermarkLabel = [[UILabel alloc] init];
+        _rotationBtn = [UIButton buttonWithType:UIButtonTypeCustom];
+        [self addSubview:_watermarkLabel];
+        [self addSubview:_rotationBtn];
+    }
+    return self;
+}
+
+- (void)layoutSubviews {
+    [super layoutSubviews];
+    _watermarkLabel.frame = CGRectMake(self.bounds.size.width / 2 - 45, self.bounds.size.height / 2 - 20, 90, 40);
+    _watermarkLabel.layer.borderWidth = 2;
+    _watermarkLabel.layer.borderColor = UIColor.blackColor.CGColor;
+    _watermarkLabel.text = @" Watermark";
+    _watermarkLabel.textColor = UIColor.redColor;
+    
+    _rotationBtn.frame = CGRectMake(self.bounds.size.width / 2 + 45 - 10, self.bounds.size.height / 2 + 20 - 10, 20, 20);
+    _rotationBtn.layer.cornerRadius = 10;
+    _rotationBtn.layer.masksToBounds = YES;
+    _rotationBtn.layer.borderColor = UIColor.blueColor.CGColor;
+    [_rotationBtn setBackgroundImage:[UIImage imageNamed:@"btn_selected"] forState:UIControlStateNormal];
+}
+
+@end

+ 35 - 0
PDFViewer/View/CPDFTextView.h

@@ -0,0 +1,35 @@
+//
+//  CPDFTextView.h
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/16.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFTextView : UIView
+
+@property (nonatomic,strong) UIButton *colorBtn;
+@property (nonatomic,strong) UISlider *textScaleSlider;
+@property (nonatomic,strong) UISlider *opacitySlider;
+@property (nonatomic,strong) UISwitch *tileSwitch;
+@property (nonatomic,strong) UILabel *rangeLabel;
+@property (nonatomic,strong) UILabel *tileLabel;
+@property (nonatomic,strong) UILabel *textLabel;
+@property (nonatomic,strong) UILabel *opacityLabel;
+@property (nonatomic,strong) UITextField *verticalField;
+@property (nonatomic,strong) UITextField *horizontalField;
+@property (nonatomic,strong) UILabel *verticalLabel;
+@property (nonatomic,strong) UILabel *horizontalLabel;
+
+@property (nonatomic,strong) NSMutableArray *colorArray;
+
+- (void)createView;
+- (void)createFrame;
+- (void)assignData;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 117 - 0
PDFViewer/View/CPDFTextView.m

@@ -0,0 +1,117 @@
+//
+//  CPDFTextView.m
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/16.
+//
+
+#import "CPDFTextView.h"
+
+#define KSCREEN_WIDTH [[UIScreen mainScreen] bounds].size.width
+#define KSCREEN_HEIGHT [[UIScreen mainScreen] bounds].size.height
+
+#define KBUTTON_WIDTH 28
+#define KBUTTON_HEIGHT 28
+
+@implementation CPDFTextView
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    
+    if (self = [super initWithFrame:frame]) {
+        [self createView];
+        [self assignData];
+    }
+    
+    return self;
+}
+
+- (void)layoutSubviews {
+    [super layoutSubviews];
+    [self createFrame];
+}
+
+- (void)createView {
+    
+    _opacitySlider = [[UISlider alloc] init];
+    _textScaleSlider = [[UISlider alloc] init];
+    _tileSwitch = [[UISwitch alloc] init];
+    _rangeLabel = [[UILabel alloc] init];
+    _tileLabel = [[UILabel alloc] init];
+    _textLabel = [[UILabel alloc] init];
+    _opacityLabel = [[UILabel alloc] init];
+    
+    _verticalField = [[UITextField alloc] init];
+    _verticalField.borderStyle = UITextBorderStyleRoundedRect;
+    
+    _verticalLabel = [[UILabel alloc] init];
+    
+    _horizontalField = [[UITextField alloc] init];
+    _horizontalField.borderStyle = UITextBorderStyleRoundedRect;
+    
+    _horizontalLabel = [[UILabel alloc] init];
+    
+    _colorArray = [NSMutableArray array];
+    for (NSInteger i = 0; i < 7; ++i) {
+        _colorBtn = [UIButton buttonWithType:UIButtonTypeSystem];
+        [_colorArray addObject:_colorBtn];
+        [self addSubview:_colorBtn];
+    }
+    
+    
+    [self addSubview:_opacitySlider];
+    [self addSubview:_textLabel];
+    [self addSubview:_opacityLabel];
+    [self addSubview:_textScaleSlider];
+    [self addSubview:_tileSwitch];
+    [self addSubview:_rangeLabel];
+    [self addSubview:_tileLabel];
+    [self addSubview:_verticalLabel];
+    [self addSubview:_verticalField];
+    [self addSubview:_horizontalField];
+    [self addSubview:_horizontalLabel];
+    
+    [self setBackgroundColor:[UIColor whiteColor]];
+    
+}
+
+- (void)createFrame {
+    // y -- 40   height -- 30
+    _opacitySlider.frame = CGRectMake(90, 40, KSCREEN_WIDTH - 100, 30);
+    _textScaleSlider.frame = CGRectMake(90, 80, KSCREEN_WIDTH - 100, 30);
+    _tileSwitch.frame = CGRectMake(100, 160, 10, 10);
+    _rangeLabel.frame = CGRectMake(10, 120, 100, 30);
+    _tileLabel.frame = CGRectMake(10, 160, 100, 30);
+    _textLabel.frame = CGRectMake(10, 80, 90, 30);
+    _opacityLabel.frame = CGRectMake(10, 40, 90, 30);
+    _verticalLabel.frame = CGRectMake(270, 160, 20, 30);
+    _verticalField.frame = CGRectMake(295, 160, 80, 30);
+    _horizontalLabel.frame = CGRectMake(165, 160, 20, 30);
+    _horizontalField.frame = CGRectMake(185, 160, 80, 30);
+    
+    NSInteger offset = 50;
+    for (NSInteger i = 0; i < _colorArray.count; i++) {
+        [[self colorArray][i] setFrame:CGRectMake(offset, 5, KBUTTON_WIDTH, KBUTTON_HEIGHT)];
+        offset += 50;
+        [[[self colorArray][i] layer] setCornerRadius:KBUTTON_WIDTH / 2];
+        [[[self colorArray][i] layer] setMasksToBounds:YES];
+    }
+    
+    [_colorArray[0] setBackgroundColor:[UIColor redColor]];
+    [_colorArray[1] setBackgroundColor:[UIColor orangeColor]];
+    [_colorArray[2] setBackgroundColor:[UIColor yellowColor]];
+    [_colorArray[3] setBackgroundColor:[UIColor greenColor]];
+    [_colorArray[4] setBackgroundColor:[UIColor blueColor]];
+    [_colorArray[5] setBackgroundColor:[UIColor brownColor]];
+    [_colorArray[6] setBackgroundColor:[UIColor purpleColor]];
+}
+
+- (void)assignData {
+    _rangeLabel.text = @"Page Range";
+    _tileLabel.text = @"Full Screen";
+    _textLabel.text = @"Font Size";
+    _opacityLabel.text = @"Opacity";
+    _verticalLabel.text = @"Y:";
+    _horizontalLabel.text = @"X:";
+}
+
+@end

二進制
PDFViewer/View/sources/btn_selected.png


PDFViewer/pdfImage@2x.png → PDFViewer/View/sources/pdfImage@2x.png