Browse Source

Merge pull request #77 from samsymons/documentation-updates

Update the documentation to include the changes made in 0.5.
Jonas Budelmann 11 năm trước cách đây
mục cha
commit
226d78b70b

+ 6 - 0
Examples/Masonry iOS Examples.xcodeproj/project.pbxproj

@@ -9,6 +9,7 @@
 /* Begin PBXBuildFile section */
 		114413091924B6EE008E702E /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 114413081924B6EE008E702E /* Default-568h@2x.png */; };
 		3DB1CAD5184538E200E91FC5 /* MASExampleArrayView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB1CAD4184538E200E91FC5 /* MASExampleArrayView.m */; };
+		4BEB55B61957394E008C862B /* MASExampleRemakeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BEB55B51957394E008C862B /* MASExampleRemakeView.m */; };
 		6C87DADA5AB046D9A3181A65 /* libPods-Masonry iOS Examples.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BDC1B8303EED42A2B01B94B1 /* libPods-Masonry iOS Examples.a */; };
 		DD175E6A182639FB0099129A /* MASExampleUpdateView.m in Sources */ = {isa = PBXBuildFile; fileRef = DD175E69182639FB0099129A /* MASExampleUpdateView.m */; };
 		DD32C3FD18E8BFF6001F6AD2 /* MASExampleAttributeChainingView.m in Sources */ = {isa = PBXBuildFile; fileRef = DD32C3FC18E8BFF6001F6AD2 /* MASExampleAttributeChainingView.m */; };
@@ -34,6 +35,8 @@
 		114413081924B6EE008E702E /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; };
 		3DB1CAD3184538E200E91FC5 /* MASExampleArrayView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASExampleArrayView.h; sourceTree = "<group>"; };
 		3DB1CAD4184538E200E91FC5 /* MASExampleArrayView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASExampleArrayView.m; sourceTree = "<group>"; };
+		4BEB55B41957394E008C862B /* MASExampleRemakeView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASExampleRemakeView.h; sourceTree = "<group>"; };
+		4BEB55B51957394E008C862B /* MASExampleRemakeView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASExampleRemakeView.m; sourceTree = "<group>"; };
 		B086DD7D31DD4B49ADC08504 /* Pods-Masonry iOS Examples.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Masonry iOS Examples.xcconfig"; path = "../Pods/Pods-Masonry iOS Examples.xcconfig"; sourceTree = "<group>"; };
 		BDC1B8303EED42A2B01B94B1 /* libPods-Masonry iOS Examples.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Masonry iOS Examples.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 		DD175E68182639FB0099129A /* MASExampleUpdateView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASExampleUpdateView.h; sourceTree = "<group>"; };
@@ -157,6 +160,8 @@
 				DDDF60CB181915E300BF7B8B /* MASExampleLabelView.m */,
 				DD175E68182639FB0099129A /* MASExampleUpdateView.h */,
 				DD175E69182639FB0099129A /* MASExampleUpdateView.m */,
+				4BEB55B41957394E008C862B /* MASExampleRemakeView.h */,
+				4BEB55B51957394E008C862B /* MASExampleRemakeView.m */,
 				DD9B4D33183CC980002BF408 /* MASExampleScrollView.h */,
 				DD9B4D34183CC980002BF408 /* MASExampleScrollView.m */,
 				3DB1CAD3184538E200E91FC5 /* MASExampleArrayView.h */,
@@ -293,6 +298,7 @@
 				DD52F255179CADC0005CD195 /* MASExampleViewController.m in Sources */,
 				DDF3875C179D648D00178773 /* MASExampleAnimatedView.m in Sources */,
 				DD7CC17617ACE990007A469E /* MASExampleDebuggingView.m in Sources */,
+				4BEB55B61957394E008C862B /* MASExampleRemakeView.m in Sources */,
 				DD9B4D35183CC980002BF408 /* MASExampleScrollView.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;

+ 3 - 0
Examples/Masonry iOS Examples/MASExampleListViewController.m

@@ -15,6 +15,7 @@
 #import "MASExampleDebuggingView.h"
 #import "MASExampleLabelView.h"
 #import "MASExampleUpdateView.h"
+#import "MASExampleRemakeView.h"
 #import "MASExampleScrollView.h"
 #import "MASExampleLayoutGuideViewController.h"
 #import "MASExampleArrayView.h"
@@ -41,6 +42,8 @@ static NSString * const kMASCellReuseIdentifier = @"kMASCellReuseIdentifier";
                                               viewClass:MASExampleBasicView.class],
         [[MASExampleViewController alloc] initWithTitle:@"Update Constraints"
                                               viewClass:MASExampleUpdateView.class],
+        [[MASExampleViewController alloc] initWithTitle:@"Remake Constraints"
+                                              viewClass:MASExampleRemakeView.class],
         [[MASExampleViewController alloc] initWithTitle:@"Using Constants"
                                               viewClass:MASExampleConstantsView.class],
         [[MASExampleViewController alloc] initWithTitle:@"Composite Edges"

+ 13 - 0
Examples/Masonry iOS Examples/MASExampleRemakeView.h

@@ -0,0 +1,13 @@
+//
+//  MASExampleRemakeView.h
+//  Masonry iOS Examples
+//
+//  Created by Sam Symons on 2014-06-22.
+//  Copyright (c) 2014 Jonas Budelmann. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface MASExampleRemakeView : UIView
+
+@end

+ 77 - 0
Examples/Masonry iOS Examples/MASExampleRemakeView.m

@@ -0,0 +1,77 @@
+//
+//  MASExampleRemakeView.m
+//  Masonry iOS Examples
+//
+//  Created by Sam Symons on 2014-06-22.
+//  Copyright (c) 2014 Jonas Budelmann. All rights reserved.
+//
+
+#import "MASExampleRemakeView.h"
+
+@interface MASExampleRemakeView ()
+
+@property (nonatomic, strong) UIButton *movingButton;
+@property (nonatomic, assign) BOOL topLeft;
+
+- (void)toggleButtonPosition;
+
+@end
+
+@implementation MASExampleRemakeView
+
+- (id)init {
+    self = [super init];
+    if (!self) return nil;
+    
+    self.movingButton = [UIButton buttonWithType:UIButtonTypeSystem];
+    [self.movingButton setTitle:@"Move Me!" forState:UIControlStateNormal];
+    self.movingButton.layer.borderColor = UIColor.greenColor.CGColor;
+    self.movingButton.layer.borderWidth = 3;
+    
+    [self.movingButton addTarget:self action:@selector(toggleButtonPosition) forControlEvents:UIControlEventTouchUpInside];
+    [self addSubview:self.movingButton];
+    
+    self.topLeft = YES;
+    
+    // make sure updateConstraints gets called
+    [self setNeedsUpdateConstraints];
+    
+    return self;
+}
+
+// this is Apple's recommended place for adding/updating constraints
+- (void)updateConstraints {
+    
+    [self.movingButton remakeConstraints:^(MASConstraintMaker *make) {
+        make.width.equalTo(@(100));
+        make.height.equalTo(@(100));
+        
+        if (self.topLeft) {
+            make.left.equalTo(self.topLeft).with.offset(10);
+            make.top.equalTo(self.top).with.offset(10);
+        }
+        else {
+            make.bottom.equalTo(self.bottom).with.offset(-10);
+            make.right.equalTo(self.right).with.offset(-10);
+        }
+    }];
+    
+    //according to apple super should be called at end of method
+    [super updateConstraints];
+}
+
+- (void)toggleButtonPosition {
+    self.topLeft = !self.topLeft;
+    
+    // tell constraints they need updating
+    [self setNeedsUpdateConstraints];
+    
+    // update constraints now so we can animate the change
+    [self updateConstraintsIfNeeded];
+    
+    [UIView animateWithDuration:0.4 animations:^{
+        [self layoutIfNeeded];
+    }];
+}
+
+@end

+ 75 - 33
README.md

@@ -1,11 +1,11 @@
-#Masonry [![Build Status](https://travis-ci.org/cloudkite/Masonry.svg?branch=master)](https://travis-ci.org/cloudkite/Masonry) [![Coverage Status](https://coveralls.io/repos/cloudkite/Masonry/badge.png?branch=master)](https://coveralls.io/r/cloudkite/Masonry?branch=master)
+#Masonry [![Build Status](https://travis-ci.org/Masonry/Masonry.svg?branch=master)](https://travis-ci.org/Masonry/Masonry) [![Coverage Status](https://coveralls.io/repos/cloudkite/Masonry/badge.png?branch=master)](https://coveralls.io/r/cloudkite/Masonry?branch=master)
 
 Masonry is a light-weight layout framework which wraps AutoLayout with a nicer syntax. Masonry has its own layout DSL which provides a chainable way of describing your NSLayoutConstraints which results in layout code that is more concise and readable.
-Masonry supports iOS and Mac OSX.
+Masonry supports iOS and Mac OS X.
 
 For examples take a look at the **Masonry iOS Examples** project in the Masonry workspace. You will need to run `pod install` after downloading.
 
-## Whats wrong with NSLayoutConstraints?
+## What's wrong with NSLayoutConstraints?
 
 Under the hood Auto Layout is a powerful and flexible way of organising and laying out your views. However creating constraints from code is verbose and not very descriptive.
 Imagine a simple example in which you want to have a view fill its superview but inset by 10 pixels on every side
@@ -36,8 +36,8 @@ UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);
                                     toItem:superview
                                  attribute:NSLayoutAttributeLeft
                                 multiplier:1.0
-                                  constant:padding.left],   
- 
+                                  constant:padding.left],
+
     [NSLayoutConstraint constraintWithItem:view1
                                  attribute:NSLayoutAttributeBottom
                                  relatedBy:NSLayoutRelationEqual
@@ -45,7 +45,7 @@ UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);
                                  attribute:NSLayoutAttributeBottom
                                 multiplier:1.0
                                   constant:-padding.bottom],
- 
+
     [NSLayoutConstraint constraintWithItem:view1
                                  attribute:NSLayoutAttributeRight
                                  relatedBy:NSLayoutRelationEqual
@@ -57,8 +57,8 @@ UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);
  ]];
 ```
 Even with such a simple example the code needed is quite verbose and quickly becomes unreadable when you have more than 2 or 3 views.
-Another option is to use Visual Format Language (VFL), which is a bit less long winded. 
-However the ascii type syntax has its own pitfalls and its also a bit harder to animate as `NSLayoutConstraint constraintsWithVisualFormat:` returns an array.
+Another option is to use Visual Format Language (VFL), which is a bit less long winded.
+However the ASCII type syntax has its own pitfalls and its also a bit harder to animate as `NSLayoutConstraint constraintsWithVisualFormat:` returns an array.
 
 ## Prepare to meet your Maker!
 
@@ -74,7 +74,8 @@ UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);
     make.right.equalTo(superview.mas_right).with.offset(-padding.right);
 }];
 ```
-Or ever shorter
+Or even shorter
+
 ```obj-c
 [view1 mas_makeConstraints:^(MASConstraintMaker *make) {
     make.edges.equalTo(superview).with.insets(padding);
@@ -102,19 +103,19 @@ These three equality constraints accept one argument which can be any of the fol
 make.centerX.lessThanOrEqualTo(view2.mas_left);
 ```
 
-MASViewAttribute           |  NSLayoutAttribute            
--------------------------  |  --------------------------   
-view.mas_left              |  NSLayoutAttributeLeft        
-view.mas_right             |  NSLayoutAttributeRight       
-view.mas_top               |  NSLayoutAttributeTop         
-view.mas_bottom            |  NSLayoutAttributeBottom      
-view.mas_leading           |  NSLayoutAttributeLeading     
-view.mas_trailing          |  NSLayoutAttributeTrailing    
-view.mas_width             |  NSLayoutAttributeWidth       
-view.mas_height            |  NSLayoutAttributeHeight      
-view.mas_centerX           |  NSLayoutAttributeCenterX     
-view.mas_centerY           |  NSLayoutAttributeCenterY     
-view.mas_baseline          |  NSLayoutAttributeBaseline  
+MASViewAttribute           |  NSLayoutAttribute
+-------------------------  |  --------------------------
+view.mas_left              |  NSLayoutAttributeLeft
+view.mas_right             |  NSLayoutAttributeRight
+view.mas_top               |  NSLayoutAttributeTop
+view.mas_bottom            |  NSLayoutAttributeBottom
+view.mas_leading           |  NSLayoutAttributeLeading
+view.mas_trailing          |  NSLayoutAttributeTrailing
+view.mas_width             |  NSLayoutAttributeWidth
+view.mas_height            |  NSLayoutAttributeHeight
+view.mas_centerX           |  NSLayoutAttributeCenterX
+view.mas_centerY           |  NSLayoutAttributeCenterY
+view.mas_baseline          |  NSLayoutAttributeBaseline
 
 #### 2. UIView/NSView
 
@@ -142,11 +143,22 @@ So if you pass a NSNumber for these attributes Masonry will turn these into cons
 make.left.lessThanOrEqualTo(@10)
 ```
 
+Instead of using NSNumber, you can use primitives and structs to build your constraints, like so:
+```obj-c
+make.top.mas_equalTo(42);
+make.height.mas_equalTo(20);
+make.size.mas_equalTo(CGSizeMake(50, 100));
+make.edges.mas_equalTo(UIEdgeInsetsMake(10, 0, 10, 0));
+make.left.mas_equalTo(view).mas_offset(UIEdgeInsetsMake(10, 0, 10, 0));
+```
+
+By default, macros which support [autoboxing](https://en.wikipedia.org/wiki/Autoboxing#Autoboxing) are prefixed with `mas_`. Unprefixed versions are available by defining `MAS_SHORTHAND_GLOBAL` before importing Masonry.
+
 #### 4. NSArray
 
 An array of a mixture of any of the previous types
 ```obj-c
-make.height.equalTo(@[view1.mas_height, view2.mas_height]); 
+make.height.equalTo(@[view1.mas_height, view2.mas_height]);
 make.height.equalTo(@[view1, view2]);
 make.left.equalTo(@[view1, @100, view3.right]);
 ````
@@ -187,7 +199,7 @@ make.edges.equalTo(superview).insets(UIEdgeInsetsMake(5, 10, 15, 20))
 
 ```obj-c
 // make width and height greater than or equal to titleLabel
-make.size.greaterThanOrEqualTo(titleLabel) 
+make.size.greaterThanOrEqualTo(titleLabel)
 
 // make width = superview.width + 100, height = superview.height - 50
 make.size.equalTo(superview).sizeOffset(CGSizeMake(100, -50))
@@ -196,16 +208,24 @@ make.size.equalTo(superview).sizeOffset(CGSizeMake(100, -50))
 #### center
 ```obj-c
 // make centerX and centerY = button1
-make.center.equalTo(button1) 
+make.center.equalTo(button1)
 
 // make centerX = superview.centerX - 5, centerY = superview.centerY + 10
 make.center.equalTo(superview).centerOffset(CGPointMake(-5, 10))
 ```
 
+You can chain view attributes for increased readability:
+
+```obj-c
+// All edges but the top should equal those of the superview
+make.left.right.and.bottom.equalTo(superview);
+make.top.equalTo(otherView);
+```
+
 ## Hold on for dear life
 
 Sometimes you need modify existing constraints in order to animate or remove/replace constraints.
-In Masonry there are two common approaches for updating constraints.
+In Masonry there are a few different approaches to updating constraints.
 
 #### 1. References
 You can hold on to a reference of a particular constraint by assigning the result of a constraint make expression to a local variable or a class property.
@@ -231,7 +251,7 @@ You could also reference multiple constraints by storing them away in an array.
 #### 2. mas_updateConstraints
 Alternatively if you are only updating the constant value of the constraint you can use the convience method `mas_updateConstraints` instead of `mas_makeConstraints`
 
-```
+```obj-c
 // this is Apple's recommended place for adding/updating constraints
 // this method can get called multiple times in response to setNeedsUpdateConstraints
 // which can be called by UIKit internally or in your code if you need to trigger an update to your constraints
@@ -248,13 +268,35 @@ Alternatively if you are only updating the constant value of the constraint you
 }
 ```
 
-You can find more detailed examples of both approaches in the **Masonry iOS Examples** project.
+### 3. mas_remakeConstraints
+`mas_updateConstraints` is useful for updating a set of constraints, but doing anything beyond updating constant values can get exhausting. That's where `mas_remakeConstraints` comes in.
+
+`mas_remakeConstraints` is similar to `mas_updateConstraints`, but instead of updating constant values, it will remove all of its contraints before installing them again. This lets you provide different constraints without having to keep around references to ones which you want to remove.
+
+```obj-c
+- (void)changeButtonPosition {
+    [self.button mas_remakeConstraints:^(MASConstraintMaker *make) {
+        make.width.equalTo(@(self.buttonSize.width));
+        make.height.equalTo(@(self.buttonSize.height));
+        
+        if (topLeft) {
+        	make.top.equalTo(@10);
+        	make.left.equalTo(@10);
+        } else {
+        	make.bottom.equalTo(self.view.mas_bottom).with.offset(-10);
+        	make.right.equalTo(self.view.mas_right).with.offset(-10);
+        }
+    }];
+}
+```
+
+You can find more detailed examples of all three approaches in the **Masonry iOS Examples** project.
 
 ## When the ^&*!@ hits the fan!
 
 Laying out your views doesn't always goto plan. So when things literally go pear shaped, you don't want to be looking at console output like this:
 
-```
+```obj-c
 Unable to simultaneously satisfy constraints.....blah blah blah....
 (
     "<NSLayoutConstraint:0x7189ac0 V:[UILabel:0x7186980(>=5000)]>",
@@ -263,16 +305,16 @@ Unable to simultaneously satisfy constraints.....blah blah blah....
     "<NSLayoutConstraint:0x7189560 V:|-(1)-[UILabel:0x7186980]   (Names: '|':MASExampleDebuggingView:0x7186560 )>"
 )
 
-Will attempt to recover by breaking constraint 
+Will attempt to recover by breaking constraint
 <NSLayoutConstraint:0x7189ac0 V:[UILabel:0x7186980(>=5000)]>
 ```
 
 Masonry adds a category to NSLayoutConstraint which overrides the default implementation of `- (NSString *)description`.
 Now you can give meaningful names to views and constraints, and also easily pick out the constraints created by Masonry.
 
-which means your console output can now look like this: 
+which means your console output can now look like this:
 
-```
+```obj-c
 Unable to simultaneously satisfy constraints......blah blah blah....
 (
     "<NSAutoresizingMaskLayoutConstraint:0x8887740 MASExampleDebuggingView:superview.height == 416>",
@@ -281,7 +323,7 @@ Unable to simultaneously satisfy constraints......blah blah blah....
     "<MASLayoutConstraint:ConflictingConstraint[0] UILabel:messageLabel.top == MASExampleDebuggingView:superview.top + 1>"
 )
 
-Will attempt to recover by breaking constraint 
+Will attempt to recover by breaking constraint
 <MASLayoutConstraint:ConstantConstraint UILabel:messageLabel.height >= 5000>
 ```