snapkit / masonry Goto Github PK
View Code? Open in Web Editor NEWHarness the power of AutoLayout NSLayoutConstraints with a simplified, chainable and expressive syntax. Supports iOS and OSX Auto Layout
License: MIT License
Harness the power of AutoLayout NSLayoutConstraints with a simplified, chainable and expressive syntax. Supports iOS and OSX Auto Layout
License: MIT License
It'd be nice if the documentation gave an example about how to animate constraints. I'd submit a pull if I knew how to form such documentation.
First off, thanks for the amazing library! You've successfully made writing autolayout code a breeze.
It would be helpful to have MASConstraintMaker
's view
property exposed so that the following code could be written:
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(make.view.superview);
}];
This way, constraints could be defined relative to the view's superview, regardless of if the superview is changed down the line in your implementation.
Additionally, this means that copy-pasting layout code when writing it would result in less occurrences of:
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(view1.superview);
}];
[view2 mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(view1.superview);
}];
Where view2 is constrained to view1's superview, which is an easy to miss but hard to debug error.
In self.view appeared black strip on the right.
If you delete line in code:
make.width.equalTo(self.mas_width).multipliedBy(multiplier);
problem disappears.
How can this be the reason?
- (void)setItems:(NSArray *)items
{
_items = items;
UIView *previousContainerItem;
for (BarButtonItem *item in _items)
{
UIView *containerItem = [[UIView alloc] init];
[self addSubview:containerItem];
[containerItem addSubview:item];
[containerItem mas_makeConstraints:^(MASConstraintMaker *make) {
MASViewAttribute *left = (previousContainerItem) ? previousContainerItem.mas_right : self.mas_left;
make.left.equalTo(left);
make.height.equalTo(self);
make.top.equalTo(self);
float multiplier = 1.0 / _items.count;
make.width.equalTo(self.mas_width).multipliedBy(multiplier); // <===
}];
[item mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(containerItem);
make.centerX.equalTo(containerItem);
make.height.equalTo(@30);
make.width.equalTo(@30);
}];
previousContainerItem = containerItem;
}
}
Screen - http://rghost.ru/50893121/image.png
when i use masonry such as this,how can i get the truly frame of imageview
imageView = [[UIImageView alloc] initWithFrame:CGRectZero];
imageView.contentMode = UIViewContentModeScaleAspectFit;
[backView addSubview:imageView];
[imageView makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(backView.mas_top).with.offset(5);
make.left.equalTo(backView.mas_left).with.offset(5);
make.width.equalTo(@300);
make.height.equalTo(@120);
}];
The most recent stuff is not covered yet, but it's too awesome to stay in the shadows :) I may do a PR if you are busy right now.
I just wanted to say how insanely useful this has been to me in developing my app. Thank you so much!
(Sorry for creating this issue just for that - but I needed you to read it, and couldn't find elsewhere to contact you...)
How do I add constraint with flipped relationship ?
I have following constraint
[self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:scrollView_
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:self.contentView
attribute:NSLayoutAttributeLeft
multiplier:1
constant:JSMessageCellPadding]];
my understanding is that following DSL
[self.contentView mas_makeConstraints:^(MASConstraintMaker *make)
{
make.left.equalTo(scrollView_.mas_left).with.offset(JSMessageCellPadding);
}];
will be equal to
[self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.contentView
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:scrollView_
attribute:NSLayoutAttributeLeft
multiplier:1
constant:JSMessageCellPadding]];
How can I do it ?
Thanks!
I am applying the constrains over the subview that is tableview of viewcontroller HelpDetailVC and i found that dealloc method is not called if we keep constrain.
__weak UIView *superview = self.view;
[self.tableview mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(superview);
}];
So if now i comment the make.edges part it start calling dealloc method.
__weak UIView *superview = self.view;
[self.tableview mas_makeConstraints:^(MASConstraintMaker *make) {
//make.edges.equalTo(superview);
}];
So can you please verify this it is an issue?
When calling a block like so:
[self.descriptionLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.titleLabel.mas_bottom).with.offset(8.f);
make.left.equalTo(self.contentView.mas_left);
make.right.equalTo(self.contentView.mas_right);
}];
Is it necessary to remove the existing constraints first?
Hi there,
First of all, I want to say that this library is really awesome and is one of the reasons that I'm using autolayout right now. Been using it for a new project and everything is working like a charm, really appreciate it.
But, I'm trying to use it on a ScrollView and I'm having a lot of trouble. I tried to solve this in multiple ways and different approaches and I'm not having any success at all. The more I try the less I feel I understand how Autolayout and Masonry works. Maybe that's the problem, not Masonry but the way Autolayout works in ScrollViews.
The main issue I have is that the scrollView only scrolls horizontally and not vertically, it's stuck.
Found this issue #12 and tried to always set the width of my subviews. I even copied exactly what he did there, but then I created like 50 views in the same scrollView and it doesn't scroll.
Been reading this https://developer.apple.com/library/ios/technotes/tn2154/_index.html but in this case, they use only one big view, and not multiple ones.
At this point, after so many hours trying, I think that I'd better see an example and start again than try to fix my own one so I created a new ViewController and added this code to the init:
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectZero];
_scrollView.backgroundColor = [UIColor grayColor];
[self.view addSubview:_scrollView];
[_scrollView makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view);
}];
NSNumber* height = [NSNumber numberWithInt:350];
UIView *view1 = [[UIView alloc] initWithFrame:CGRectZero];
view1.backgroundColor = [UIColor blueColor];
[_scrollView addSubview:view1];
UIView *view2 = [[UIView alloc] initWithFrame:CGRectZero];
view2.backgroundColor = [UIColor greenColor];
[_scrollView addSubview:view2];
UIView *view3 = [[UIView alloc] initWithFrame:CGRectZero];
view3.backgroundColor = [UIColor redColor];
[_scrollView addSubview:view3];
[view1 makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(@0);
make.left.equalTo(@0);
make.width.equalTo(_scrollView.width);
make.height.equalTo(height);
}];
[view2 makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(view1.mas_bottom);
make.left.equalTo(@0);
make.width.equalTo(_scrollView.width);
make.height.equalTo(height);
}];
[view3 makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(view2.mas_bottom);
make.left.equalTo(@0);
make.width.equalTo(_scrollView.width);
make.height.equalTo(height);
}];
This code adds the first view and the next two correctly, one using the bottom as a top reference, but the UISCrollView is not scrolling at all. I also tried to add everything inside a UIView. I even tried to get the last object Y position, but I get a very high number that doesn't make sense.
Should I have to set the contentSize of the scrollView ? but that's why I wanted the Y position for, I'm feeling that this is the wrong direction.
At this point I hope that somebody can help me, I will really appreciate it, and even better, seeing some example. I think I'm missing something here.
Thanks in advance :)
If I have a view with constraints:
[self.summaryView makeConstraints:^(MASConstraintMaker *make) {
self.animatableConstraint = make.edges.equalTo(self.view).with.insets(UIEdgeInsetsMake(80, 10, 10, 10));
}];
And later I want to animate to another point like:
// TODO: Set new position here.
[UIView animateWithDuration:2.5
animations:^{
[self.summaryView layoutIfNeeded];
}
completion:^(BOOL finished) {
}];
How can I do this?
HI,
i've been using Masonry now for the past week and it's awesome.
But i have a question and perhaps you could add it to the examples. How do you do calculations in the equalTo function?
I want to do something like have a view which has a width the same as its superview but, the height should only be a third. Normally i would do CGRectGetWidth(superView.bounds) / 3, but how should i do it with Masonry?
[myView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(superView);
make.width.equalTo(superView.mas_width);
make.height.equalTo(superView.mas_width); //It needs to be a third of the width
}];
thx!
This seems like a bug since a comment inside the method says that it checks everything except the constant.
Hi Jonas,
I'm seeing a strange issue which I think I should raise.
I've been quite happily using the shortcut in my project for mapping against a superview's offset,
e.g. inside a UIView subclass, when adding a subview, for configuring its constraints instead of writing
make.top.equalTo(self).with.offset(20)
I'd just write
make.top.offset(20)
which adds the same constraint. This has been working great except for a case i've came across - where the view is a UITableViewCell. I've uploaded an example project here which outlines exactly where it works for one case, and not for the other.
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
UILabel *label = [UILabel new];
label.text = @"Label";
[self addSubview:label];
[label mas_makeConstraints:^(MASConstraintMaker *make){
// /* Broken */
// make.top.offset(20);
// make.right.offset(-20);
/* Works */
make.top.equalTo(self).with.offset(20);
make.right.equalTo(self).with.offset(-20);
}];
}
return self;
}
I'm unsure whether it's a fault in Masonry or UIKit, but I figured you're better at debugging this than me so I'd ask you first!
So, I downloaded a zip of your archive, ran pod install
, opened up the workspace, and switched my target to the example project. When I hit Run, it gave me a compile error saying that Masonry.h couldn't be found (from the example project's PCH file).
I had to modify the import line to be:
#import "Masonry/Masonry.h"
for it to work.
This is in Xcode 4.6.3.
Hey I have some constraints that are oddly breaking and am hoping you can help me out.
Here's the scenario. I have a UIViewController with a custom toolbar at the bottom. The toolbar has 4 buttons, all equal height, and when switching between portrait and landscape mode the button widths will adjust equally to fill the view width. This works great when I test this in a ViewController that only has this custom toolbar.
However, in one of my more complex UIViewControllers that has many subviews with constraints, the toolbar constraint is breaking on the button widths.
I've tested on these devices.
iPhone 4 iOS 6 - breaks
iPad Mini iOS 6 - does not break
iPhone Simulator iOS 6 - breaks
iPhone Simulator iOS 7 - does not break
Here's my init function in my custom toolbar class. At the bottom of the function is where I do the auto layout for my toolbar. I must not be creating equal widths properly?
(id)init
{
self = [super init];
if (self) {
// Initialization code here.
BOOL isIphone = [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone;
CGSize screenSize = [UIScreen mainScreen].bounds.size;
CGFloat viewHeight;
if (isIphone)
{
viewHeight = 80.0f;
}
else//iPad
{
viewHeight = 100.0f;
}
self.view = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, screenSize.width, viewHeight)];
self.view.backgroundColor = [UIColor grayColor];
//add buttons
_buttons = [[NSMutableArray alloc] init];
UIButton *button;
//CGFloat buttonWidth = screenSize.width / 4.0f;
CGFloat buttonHeight = viewHeight;
for (NSUInteger i = 0; i < 4; ++i)
{
button = [UIButton buttonWithType:UIButtonTypeCustom];
[_buttons addObject:button];
[self.view addSubview:button];
}
//auto layout
UIButton *button0 = [_buttons objectAtIndex:0];
UIButton *button1 = [_buttons objectAtIndex:1];
UIButton *button2 = [_buttons objectAtIndex:2];
UIButton *button3 = [_buttons objectAtIndex:3];
self.view.mas_key = @"self.view";
button0.mas_key = @"button0";
button1.mas_key = @"button1";
button2.mas_key = @"button2";
button3.mas_key = @"button3";
[button0 mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view.mas_left);
make.bottom.equalTo(self.view.mas_bottom);
make.right.equalTo(button1.mas_left);
make.width.equalTo(button1.mas_width);
make.height.equalTo([NSNumber numberWithFloat:buttonHeight]);
}];
[button1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(self.view.mas_bottom);
make.left.equalTo(button0.mas_right);
make.right.equalTo(self.view.mas_centerX);
make.width.equalTo(button0.mas_width);
make.height.equalTo([NSNumber numberWithFloat:buttonHeight]);
}];
[button2 mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(self.view.mas_bottom);
make.left.equalTo(self.view.mas_centerX);
make.right.equalTo(button3.mas_left);
make.width.equalTo(button3.mas_width);
make.height.equalTo([NSNumber numberWithFloat:buttonHeight]);
}];
[button3 mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(self.view.mas_bottom);
make.left.equalTo(button2.mas_right);
make.right.equalTo(self.view.mas_right);
make.width.equalTo(button2.mas_width);
make.height.equalTo([NSNumber numberWithFloat:buttonHeight]);
}];
}
return self;
}
The documentation shows the following example for the updateConstraints methods. The updateConstraints method is called at the top of the method.
- (void)updateConstraints {
[super updateConstraints];
[self.growingButton mas_updateConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self);
make.width.equalTo(@(self.buttonSize.width)).priorityLow();
make.height.equalTo(@(self.buttonSize.height)).priorityLow();
make.width.lessThanOrEqualTo(self);
make.height.lessThanOrEqualTo(self);
}];
}
The updateConstraints method in MASExampleUpdateView.m calls the updateConstraints method at the bottom of the method.
// this is Apple's recommended place for adding/updating constraints
- (void)updateConstraints {
[self.growingButton updateConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self);
make.width.equalTo(@(self.buttonSize.width)).priorityLow();
make.height.equalTo(@(self.buttonSize.height)).priorityLow();
make.width.lessThanOrEqualTo(self);
make.height.lessThanOrEqualTo(self);
}];
//according to apple super should be called at end of method
[super updateConstraints];
}
I believe the updateConstraints method in MASExampleUpdateView.m is correct, but the documentation and MASExampleUpdateView.m should use the same method to update constraints.
I often use a pattern as the following:
- (instancetype)init...
UIView * mySubView = [UIView new];
[myView addSubview:mySubView];
[mySubView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(mySubView.superview);
}];
So I refer to myView indirectly using mySubView.superview. This is because it often eases refactoring, for instance if I want to introduce a container view between myView and mySubView.
I wonder if it would make sense to introduce a make.superview? This way, the constraints related to the actual view would be easier to recognize.
Also, I try to use mas_makeConstraints: as often as I can, since in my mind, constraints are almost always immutable, except when animating.
What are your comments to the above points? Are they patterns or anti-patterns? :-)
When setting a constraint equalTo a NSNumber, and afterwards setting it to equalTo(self) in an updateConstraints block, the constraint is not recognised as needed to be updated, and instead two constraints are added and an autolayout error (cannot satisfy constraints) is thrown, which shows two simultaneously installed width constraints.
Example:
[self.containerView mas_updateConstraints:^(MASConstraintMaker *make) {
if (something) {
make.width.equalTo(@760);
} else {
make.width.equalTo(self);
}
}];
A workaround i had to use was to take the width of self manually and wrap it in a NSNumber like this:
[self.containerView mas_updateConstraints:^(MASConstraintMaker *make) {
if (something) {
make.width.equalTo(@760);
} else {
make.width.equalTo(@(self.bounds.size.width));
}
}];
How to use this for a swift project,Can you show me an example?
Would it be possible to change the styling of a UIView by changing the styleClass to a different string?
It seems that setting translatesAutoresizingMaskIntoConstraints=NO on the root view (i.e., the root view controller's view) has a bad effect on auto layout. Masonry implicitly changes that setting, so if it is used in the wrong way, it can cause nasty bugs.
HOW TO REPRODUCE: (I'll try to provide a toy example later, when time is less desperately tight, if desired)
translatesAutoresizingMaskIntoConstraints=NO
on window.rootViewController.view
.THE WORKAROUND: If RV is the root view and SV is a subview, then avoid calls of the form:
[RV.makeConstraints .... {
... SV ...
}]
and instead use:
[SV.makeConstraints ... {
... RV ...
}]
Note that this situation doesn't apply to every superview/subview relation, only when the superview is the topmost view.
THE FIX? Probably Masonry should check to see if the view on which the Masonry method is being called is the root view, before setting translatesAutoresizingMaskIntoConstraints to NO.
(This is the second time that implicit property change has bitten me. I'm not sure if it's worth the convenience.)
(P.S. Apologies if this is already reported or even documented. I searched but couldn't find anything.)
After I started using classy.as for my styling I have quickly become addicted to the live reloading feature. I'm thinking if we could somehow do something similar for Masonry it would be awesome. I don't know how this would work thought.
It's mostly my constant numbers I would like to change live. Today I use DCIntrospect (https://github.com/lukaswelte/DCIntrospect-ARC) to adjust frames in the simulator and then I have to remember the new constant values and change them in the code afterwards.
Could we define all constants in a separate file that is watched by Masonry. So that changes in the constant file would be injected into the running simulator?
Support for building constraints with topLayoutGuide and bottomLayoutGuide would be great. From what I understand, using the length property of the guide to build the constraint would require us to also monitor for status bar frame changes, and reconfigure our constraints.
This looks like it would be difficult to support without a big refactor, but if you have ideas for how you'd like this implemented, I'd be happy to work on it.
As mentioned in Apples Transitioning to ARC Release Notes you can't create a weak reference to instances of class NSTextView. Meaning the app will crash if you are trying to call mas_makeConstraints: on a NSTextView.
Since i love using Masonry, I would love to see this being implemented so that I can use it for my Mac OS X projects as well.
Do you see this feature being implemented or will you go on not supporting this?
Thanks!
Hi there
First of all, thanks for Masonry, it looks really awesome! Unfortunately though, I have the following problem: I created a UIScrollView
inside the UIView
of my UIViewController
and added some constraints to keep the scroll view the size of the view:
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectZero];
_scrollView.backgroundColor = [UIColor redColor];
[self.view addSubview:_scrollView];
[_scrollView makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view);
}];
This seems to work, but then I added a UIView
inside the scroll view and tried to make it stick to the top:
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.backgroundColor = [UIColor blueColor];
[_scrollView addSubview:view];
[view makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(@0);
make.left.equalTo(@0);
make.right.equalTo(@0);
make.height.equalTo(@100);
}];
However, this second view never shows up! Any idea on what I'm doing wrong?
I am using a transparent UINavigationBar
and UITextField
. I want it to be 20px under the navigation bar, so I'm using the following commands:
[self.emailTextField mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo((self.view).mas_top).with.offset(20);
}];
However, my text field appears beneath the navigation bar, 20px from the top of the screen.
-- iOS 7 SPOILER ALERT --
In iOS 7 there is a topLayoutGuide
property on UIViewController
. How can I incorporate it using Masonry, so my text field appears under the navigation bar (84px from the top of the screen) both in iOS 7 with transparent navigation bar and in iOS 6?
I know that it can be done using NSLayoutConstraints
. Taken from the documentation:
id topGuide = myViewController.topLayoutGuide;
// "button" is a UIButton object specified elsewhere
[myViewController.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[topGuide]-20-[button]"]];
I have a UIView (hegiht=80), and as subviews a label and a edit.
I have tried to center both in the Y axis. However, the heigth of both subviews change to be the same of the superview.
I expected to both controls to be centered.
[self.view addSubview:scroll];
self.view.backgroundColor = [UIColor darkGrayColor];
UIEdgeInsets paddingInsets = UIEdgeInsetsMake(self.navigationController.navigationBar.frame.size.height + 30, self.padding, self.padding, self.padding);
[scroll keepInsets:paddingInsets];
UIView *back = [[UIView alloc] init];
back.backgroundColor = [UIColor lightGrayColor];
[scroll addSubview:back];
[back mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(@0);
make.left.equalTo(@0);
make.width.equalTo(scroll.mas_width);
make.height.equalTo(@80);
}];
[label mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(back);
make.left.equalTo(@0);
make.width.equalTo(@200);
make.centerY.equalTo(back.mas_centerY);
}];
[edit mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(back);
make.right.equalTo(back.mas_right);
make.width.equalTo(label.mas_width);
make.centerY.equalTo(back.mas_centerY);
}];
I'm having a strange issue with animating a certain constraint.
I created a very simple project to demonstrate the issue:
https://github.com/mobitar/MasonryTest
In ListViewController.m
, there's a method called addSampleView
. If you uncomment this method, and hit the "Toggle" button, the list controller slides out with an animation, as intended.
If however you leave this line in, and the sample view is added, for some reason the list controller slides out and in when you hit the toggle button, but without animation.
Any idea why?
If the flag -Wmismatched-return-types
is set, the new property attribute
from MASShorthandAdditions
introduced in v0.5.0 will raise a warning when forwarding it to the non-shorthand equivalent.
This is the output from the compiler:
conflicting return type in implementation of 'attribute': 'MASViewAttribute *(^)(NSLayoutAttribute)' vs 'MASViewAttribute *' [-Wmismatched-return-types]
MAS_ATTR_FORWARD(attribute);
The CocoaPods project recommends to have Podfile.lock under version-control.
I love Masonry to bits. It makes a ton of difference for me and enjoy using it on a daily basis. In that light I'd like to offer some constructive feedback.
I have an issue with the implementation: The MASConstraintMaker design and syntax violates basic Objective-C conventions. Obj-C properties are used in ways they were not intended to be used. I think it's wrong to fight the language because although immediate readability may increase, it decreases implementation transparancy; the implicit conventions and expectation management between an API developer and the API user vanishes and it generally clutters the code if developers create their own conventions instead of following the ones given by the language. Moreover, you're not only fighting the language, you're also fighting the IDE.
Of course, this is what I'm talking about:
[someView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(otherView).with.offset(someOffset);
}
Instead I suggest a syntax more like this:
[someView mas_makeConstraints:^(MASConstraintMaker *maker) {
[maker setLeftEqualTo:otherView withOffset:someOffset];
}
Of course this would require a lot of new methods to cover all cases, but I think its more in line with language conventions and any Objective-C programmer with minimal experience will read this just as easily as the current syntax. An added benefit is that this syntax autocompletes much nicer in Xcode because you don't have to interrupt the auto completion with dots all the time.
I'd just like to start a discussion regarding this issue. I hope we can come up with a great solution that is more in line with the Obj-C language conventions while maintaining Masonry's simplicity and elegance.
Maybe it is my misunderstanding about how AutoLayout or Masonry work, but it seems to me like the order of calling -makeContraints:
in iOS7 is somehow order dependant.
Here is a very simple example:
A very simple view, with a yellow view on top and a blue view on bottom:
Expected Result (Gist)
[blueView makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(yellowView.bottom).offset(padding);
make.bottom.equalTo(superview.bottom).offset(-padding);
make.left.equalTo(superview.left).offset(padding);
make.right.equalTo(superview.right).offset(-padding);
}];
[yellowView makeConstraints:^(MASConstraintMaker *make) {
make.top.greaterThanOrEqualTo(superview.top).offset(padding);
make.left.equalTo(superview.left).offset(padding);
make.right.equalTo(superview.right).offset(-padding);
make.height.equalTo(@100);
}];
All I do is switch the order -makeContraints:
is called, calling yellowView first :
Possible Bug Result (Gist)
[yellowView makeConstraints:^(MASConstraintMaker *make) {
make.top.greaterThanOrEqualTo(superview.top).offset(padding);
make.left.equalTo(superview.left).offset(padding);
make.right.equalTo(superview.right).offset(-padding);
make.height.equalTo(@100);
}]
[blueView makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(yellowView.bottom).offset(padding);
make.bottom.equalTo(superview.bottom).offset(-padding);
make.left.equalTo(superview.left).offset(padding);
make.right.equalTo(superview.right).offset(-padding);
}];
On iOS6 this seems to work fine.
So is this a bug or am I missing something?
My use case is pretty simple: call mas_makeConstraints:
on some views. I do this in several places and everything worked perfectly with 0.3.0. As soon as I updated to 0.4.0, I started seeing these exceptions:
-[UILabel mas_makeConstraints:]: unrecognized selector sent to instance 0x14989a80
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UILabel mas_makeConstraints:]: unrecognized selector sent to instance 0x14989a80'
No code has changed. I am importing <Masonry/Masonry.h> and the project builds just fine. Were there breaking changes that weren't mentioned in the README?
The following code will not work as expected:
make.width.equalTo(@200).with.offset(-40);
Instead of the expected constant value of 160
, this will set up a constraint with -40
as constant.
Since Pods
are out of .gitignore
now, Pods.xcodeproj
is now included in the repo. However, Podfile
specifies a build phase generation which involves a full path to the script:
export | egrep '( BUILT_PRODUCTS_DIR)|(CURRENT_ARCH)|(OBJECT_FILE_DIR_normal)|(SRCROOT)|(OBJROOT)' > /Users/jonas/Projects/Masonry/script/env.sh
So you can't run tests unless you run pod
to regenerate it for yourself.
I'm not quite sure how to fix this properly, so leaving it here for now :)
First of all, I don't know if this is really an issue of Masonry or an Auto Layout thing.
I'd been doing some tests animating things with Masonry and after some tweaking it usually works like a charm and is pretty fast. I want to share one of these tests with you which is perfect to show the issue I had and the workaround used.
https://github.com/lluisgerard/Masonry-Animated-Cell
As you can see here. I have a view that starts always at width 0 and grows to the pixel equivalent percentage (from 0 to 300 px).
The basic code for this animation is where self.animateConstraint is animated:
float width = self.frame.size.width / grade;
self.animateConstraint.equalTo(@(width));
[UIView animateWithDuration:1.0f
delay:0.0f
usingSpringWithDamping:0.4f
initialSpringVelocity:0.9f
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
[self layoutIfNeeded];
} completion:^(BOOL finished) {
}];
What happens is that when you start the app for the first time (aka load the tableview) the growing view doesn't animate at all. It just appears on the cell with the end state of the animation.
I don't know the best way to approach this, maybe there is something that I'm missing like a trigger when the view is completely loaded and constraints are set (delegates?). I even found other issues that I cannot replicate now, like the bar started to grow while the whole view was being set by autolayout (I think I was using updateConstraints then).
Ok, the solution (or workaround) I found was to do this only the first init:
double delayInSeconds = 0.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
growBlock(); // this block is the above animation code
});
As you can see, delay is set to 0 seconds but the dispatch_after
is enough to activate the first animation. You can download my example project, comment the dispatch, you will see that nothing is animated on the first load then.
You can see the whole code here https://github.com/lluisgerard/Masonry-Animated-Cell/blob/master/AnimateLayouts/LLGAnimatedView.m
I'm sure I'm missing something here to know when the autolayout finished doing it's job (maybe tracking self.frame width and height?). Anyway, I hope that at least somebody can enjoy my example :)
I'm having some issues with the app that I'm developing right now. Not sure where is the problem but I can replicate it whenever I want. Not sure if this is a Masonry issue though. So far, I tested the drawer menu without autolayout on iOS7.1 and I'm not having the same problems there, that's why I think that at least autolayout is involved here.
I'm using this "drawer" menu:
https://github.com/monospacecollective/MSDynamicsDrawerViewController
This is how it looks usually (can't share it without hiding some parts):
If you go and change from one view to another and you go "slow", letting the whole view load (sometimes it goes to the API on the background to load content), everything works fine.
The issue comes if you open the drawer menu before its content is entirely loaded, then the view seems that is cut in half and so the menu (sometimes disappears).
I can't share my code but maybe someone has an idea about why this is happening, or you are having also some issues after upgrading to iOS 7.1. If nothing comes up I will try to replicate this on a separated project only for this purpose.
Thank you very much in advance! Sorry if you think that this is not to be posted here, I'm having some degree of desperation right now ๐น
- (MASConstraint *)and;
When compiling my Swift project with this project included in my bridging header, I get a compilation error due to this line above. The error is as follows:
<unknown>:0: error:
/path/to/Pods/Headers/Masonry/MASConstraint.h:113:
expected selector for Objective-C method
When I comment out the line, compilation proceeds quite happily.
This is based off of head, latest commit being bec7297 (so this includes the fix from #84). Am I doing something wrong, or missing something?
Hello, i've code like this
self.nameLabel.text = "super long long long long text";
[self.nameLabel makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.contentView.left).offset(10);
make.top.equalTo(self.contentView.top).offset(10);
make.right.equalTo(self.contentView.right).offset(-10).priorityLow();
}];
As you can see it has the constraint make the the label all the way to right - 10px.
But when you add priority after offset it doesn't work, the label just overflow and ignore the right
and offset
.
In other words it's behaving the same like you don't specify any right constraint like code below
self.nameLabel.text = "super long long long long text";
[self.nameLabel makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.contentView.left).offset(10);
make.top.equalTo(self.contentView.top).offset(10);
}];
Thank you
Hi!
I use Masonry in my real cocoa project. All things are cool before adding support for the animator proxy on OS X #41 .
Arter #41 All my teammate except me have the following problem:
So I do some test:
I noticed you can't get to the animator proxy on OSX using Masonry. I was thinking of adding this feature, but before I do, do you have any idea on the best way to expose this?
This is a OSX only feature, and I don't want to sprinkle the code with #ifdefs, and also don't want to expose the underlying NSLayoutConstraint(s) on the MASConstraint protocol.
I thought about adding a delegate method, but that's far from elegant.
Maybe adding this to MASConstraint protocol:
#ifdef TARGET_OS_MAC && !TARGET_OS_IPHONE
@property (nonatomic, copy, readonly) id<MASConstraint> (^animated)(BOOL useAnimator);
#endif
- (void)update:(void (^)(id<MASConstraint>)block;
After installing a constraint, updating it would be something like:
[self.heightConstraint update:^(id<MASConstraint> constraint){
constraint.equalTo(@(100)).animated(YES);
}];
What do you think?
I plan to use masonery to build forms. I try to follow the examples but found it not enough.
For example, if I try to recreate
https://stripe.com/docs/checkout
(click in pay with card), I need to:
So far, I have only work by trial and error and mainly things work with exact values (defeating the use of a layout manager).
I'm sure I have not get the library (neither with https://github.com/iMartinKiss/KeepLayout) so some more complete examples could help
Currently when trying to set constraints in Swift using the objc Masonry files, an error is generated: Cannot convert the expression's type '$T6' to type '() -> ((AnyObject!) -> MASContraint!)!'
I have been working on login module. I have created the login view like this.
[loginview mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(@(kLoginContainerYPosition));
make.centerX.equalTo(self.view.mas_centerX);
make.width.equalTo(@(kLoginContainerViewWidth));
make.height.equalTo(@(kLoginContainerViewHeight));
}];
When keyboard pops up I tried to update login view y position like below. But could not able update view position.
(void)keyboardWillBeShown {
[loginCompanyViewController.view mas_updateConstraints:^(MASConstraintMaker *make) {
CGFloat kContentPaddingForIPad = kLoginContainerYPosition - 100;
make.centerY.equalTo(@(kContentPaddingForIPad));
}];
}
Can you please help me out.
I setup a UIView to wrap UIControls, like:
aView
-- UISlider
-- UIImageView
-- UIImageView
in the aView's method: - (id)initWithFrame:(CGRect)frame, I setup all subviews and controls, make masonry layout.
Then add the aView on self.view. But the slider's thumb can not be moved.
Please help me to figure out.
If I add titleEdgeInsets to UIButton whole width of a button stays the same as it would without inset and titleLabelText just doesn't display properly
I don't quite understand this from the readme:
An array of a mixture of any of the previous types
make.height.equalTo(@[view1.mas_height, view2.mas_height]);
Does make.height.equalTo(@[view1.mas_height, view2.mas_height]);
make the height of what ever view we're adding constraints to the average of the view1
and view2
heights?
"Important
Call [super updateConstraints] as the final step in your implementation."
In your examples, you are calling it first. As I was five minutes ago.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.