Jane books migration
# the premise
After some time, I find that there are few navigation tutorials online, and only one or two. Here I would like to compile some methods I would like to use for you to learn.
Navigation is a third-party library for AutoLayout. It uses the link syntax to retrieve the code you would like to retrieve. Therefore, learning costs will be significantly lower than those for AutoLayout and VFL.
# prepared
In making https://github.com/SnapKit/Masonry download configuration third-party libraries, basic usage also have instructions in the Readme, I will not go into, CocoaPods in my blog have related Settings introduced CocoaPods install and use
pod 'Masonry'
Copy the code
‘~> X.X.X ‘is not used to update the library.
Add to PCH file
#import "Masonry.h"
Copy the code
Can be used globally
# Basic usage
Can understand and Android five layout of the relative layout, the basic principle is the position of the control relative to a control, so the relative comparison needs to have a reference control
The basic calculation formula is
Control left = right of reference control + offset value (5) (control is to the right of reference control, 5px away)
make.left.equalTo(view.superview.mas_right).offset(10); // If left blank, the default is leftCopy the code
# Supported attributes
@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;
Copy the code
# # method
There are three ways to set constraints for navigation
Using updateconstraints for the first time, you will remove all of the previous constraintsCopy the code
Note: when circulating the cell where code is called repeatedly, use mas_remakeConstraints to prevent the same constraints being generated when circulating, which may be held in performance, even when used with make to prevent unnecessary constraints being generated
# Simple usage
Initializes a view with margins
UIView *view = [[UIView alloc] init]; view.backgroundColor = [UIColor redColor]; [self.view addSubview:view]; // Add the parent control first, [MASConstraintMaker *make] { make.edges.equalTo(view.superview).insets(UIEdgeInsetsMake(20, 20, 20, 20)); }];Copy the code
equivalent
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.top.bottom.equalTo(view.superview).insets(UIEdgeInsetsMake(20, 20, 20, 20));
Copy the code
Left,right, and other attributes, as literal
equivalent
[view mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(view.superview).offset(20); make.top.equalTo(view.superview).offset(20); make.right.equalTo(view.superview).offset(-20); make.bottom.equalTo(view.superview).offset(-20); }];Copy the code
In chained syntax, and and with are both modifiers that don’t do anything and are easy to understand
make.bottom.and.top.equalTo(view.superview).with.offset(-20);
Copy the code
In the source
#pragma mark - Semantic properties
- (MASConstraint *)with {
return self;
}
- (MASConstraint *)and {
return self;
}
Copy the code
A child control is half the width of the parent control.
[view mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(view.superview); Make. Top. EqualTo (view. Superview). Offset (20); make the width, height, equalTo (view. Superview.) multipliedBy (0.5);}];Copy the code
## is greater than or less than
make.width.greaterThanOrEqualTo(@200);
make.width.lessThanOrEqualTo(@400)
Copy the code
## Use constraints for judgment in BLCOK (when unifying some business)
[self.button mas_remakeConstraints:^(MASConstraintMaker *make) {
make.size.equalTo(self.buttonSize);
if (topLeft) {
make.top.and.left.offset(10);
} else{ make.bottom.and.right.offset(-10); }}]; Dead altitude 300 x 300Copy the code
## Modify the specified constraint
MASConstraint *topConstraint; // While generating constraints [view1 mas_makeConstraints:^(MASConstraintMaker *make) {topConstraint = make.top.equalTo(superview.mas_top); make.left.equalTo(superview.mas_left); }]; . // Modify the constraint later [topConstraint uninstall];Copy the code
## Write dead height 300 * 300
[view mas_makeConstraints:^(MASConstraintMaker *make) { make.center.equalTo(view.superview); make.width.height.equalTo(@300); }];Copy the code
## About mas_equalTo use
You’ll find two ways to say equivalence: equalTo and mas_equalTo
Mas_equalTo is really just a macro with an extra layer of processing, because equalTo doesn’t support basic data types
#define mas_equalTo(...) equalTo(MASBoxValue((__VA_ARGS__)))
Copy the code
In the height 300 constraint, we could write it like this
mak.height.equalTo(@300);
Copy the code
You can also use mas_equalTo. In general, I will use mas_equalTo for all the encapsulation of basic data types
mak.height.mas_equalTo(300);
Copy the code
## Parallel sort – level or height
Often encounter a lot of need to equal width or height sorting requirements, the following is a method I use personally, you can refer to it, but it needs to be noted that the various uses of the relative layout are many, please think about it, the same effect, N kinds of writing
- (void)viewDidLoad { [super viewDidLoad]; NSMutableArray *viewArray = [NSMutableArray array]; NSArray *colorArray = @[[UIColor redColor],[UIColor blueColor],[UIColor orangeColor],[UIColor purpleColor]];for (int i = 0; i < colorArray.count ; i++) {
UIView *view = [[UIView alloc] init];
view.backgroundColor = colorArray[i];
[self.view addSubview:view];
[viewArray addObject:view];
}
[self sortVerticalWithViews:viewArray LeftMargin:50 Width:100 BackViewHeight:300];
viewArray = [NSMutableArray array];
for (int i = 0; i < colorArray.count ; i++) {
UIView *view = [[UIView alloc] init];
view.backgroundColor = colorArray[i];
[self.view addSubview:view];
[viewArray addObject:view];
}
[self sortHorizontalWithViews:viewArray TopMargin:320 TopView:self.view Height:100];
}
#pragma mark sorts controls to update their operations (horizontal)- (void)sortHorizontalWithViews:(NSArray *)views TopMargin:(NSInteger)topMargin TopView:(UIView *)topView Height:(NSInteger)viewH { __block UIView *leftView; [views enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { UIView *tempView = obj; [tempView mas_remakeConstraints:^(MASConstraintMaker *make) {if (idx == 0) {
make.left.equalTo(tempView.superview);
if([withmicrosoft isEqual: tempView superview]) {/ / if the incoming container view has no control over the make the top. The mas_equalTo (withmicrosoft). Offset (topMargin); }else {
make.top.mas_equalTo(topView.mas_bottom).offset(topMargin);
}
make.width.mas_equalTo(tempView.superview.mas_width).multipliedBy((CGFloat)1 / views.count);
make.height.mas_equalTo(viewH);
} else{ make.left.equalTo(leftView.mas_right); make.top.mas_equalTo(leftView); make.width.mas_equalTo(leftView); make.height.equalTo(leftView); }}]; leftView = tempView; }]; }#pragma Mark sorts controls and updates their operations (vertically)- (void)sortVerticalWithViews:(NSArray *)views LeftMargin:(NSInteger)leftMargin Width:(NSInteger)viewWidth BackViewHeight:(NSInteger)backViewHeight { __block UIView *topView; [views enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { UIView *tempView = obj; [tempView mas_remakeConstraints:^(MASConstraintMaker *make) {if (idx == 0) {
make.left.equalTo(tempView.superview).offset(leftMargin);
make.top.mas_equalTo(tempView.superview);
make.width.mas_equalTo(viewWidth);
make.height.mas_equalTo(backViewHeight / views.count);
} else{ make.left.equalTo(topView); make.top.mas_equalTo(topView.mas_bottom); make.width.mas_equalTo(topView); make.height.mas_equalTo(topView); }}]; topView = tempView; }]; }Copy the code
# Animation problem
Animation problem, and the normal method implementation is similar, the emphasis is to modify the constraint after the call
[view.superview layoutIfNeeded];
Copy the code
“
[view mas_makeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(400); make.left.mas_equalTo(100); make.size.mas_equalTo(CGSizeMake(100, 100)); }]; [view.superview layoutIfNeeded]; // If you need to animate the constraint before it is generated, force the refresh first before writing the animation. [UIView animateWithDuration:3 animations:^{[view mas_updateConstraints:^(MASConstraintMaker *make) { Make.left. Mas_equalTo (200);}]; [view.superview layoutIfNeeded];// Force draw}];Copy the code
Multiple controls are centered relative to the parent control
In this case, it is most convenient to put multiple child controls in a container, let the container adjust the width of the child controls, and center the container relative to the parent control
- For convenience, I use a blank superView in the XIB to occupy the space, which is easy to adjust later
General steps:
- Add the parent control to the container
- Sets the position of the container relative to the parent control
- Loop to create child controls
- (void)initCouponType:(PPProductDetailViewModel *)viewModel { UIView *conView = [[UIView alloc] init]; [self.couponTypeContainer addSubview:conView]; / / parent to join container [conView makeConstraints: ^ (MASConstraintMaker * make) {make. Height. Top. CenterX. EqualTo (conView. Superview); //width is not set, so that it ADAPTS to the child control width}]; __block UIView *lastView = nil; For me. / / the viewModel couponTypeArray data source, configuration according to actual situationif(viewModel.couponTypeArray.count > 0) { [viewModel.couponTypeArray enumerateObjectsUsingBlock:^(GwCouponType *_Nonnull Coupontype, NSUInteger IDX, BOOL *_Nonnull stop) {UIButton *newBtn = [[UIButton alloc] init]; [newBtnsetTitle:coupontype.couponTypename forState:UIControlStateNormal]; // Add child controls to the container [conView addSubview:newBtn]; [newBtn makeConstraints:^(MASConstraintMaker *make) { // Left make.left. EqualTo (lastView? Lastview.mas_right: Newbtn.superview).offset(3); // The last child control sets the right aligned containerif(idx == viewModel.couponTypeArray.count - 1) { make.right.equalTo(newBtn.superview).offset(3); } // Align the child with the parent in the Y-axis of make.centery. EqualTo (newbtn.superview); // lastView lets the next control know what is to its left, setting the left attribute lastView = newBtn; }]; }]; }}Copy the code
#Cell height calculation
Reference star club Dai Ming @ method [AutoLayout frame Masonry use result] also can reference forkingdog FDTemplateLayoutCell (http://www.jianshu.com/p/24e4ff56bfea)
- IOS8 above
tableView.rowHeight = UITableViewAutomaticDimension; tableView.estimatedRowHeight = 80; - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {returnUITableViewAutomaticDimension; }}Copy the code
- iOS7
@interface DataModel: NSObject @property (copy, nonatomic) NSString *text; @property (assign, nonatomic) CGFloat cellHeight; @end - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {static CustomCell *cell; Cell static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([CustomCell class])]; }); DataModel *model = self.dataArray[(NSUInteger) indexPath.row];if(model.cellHeight <= 0) { [cell makeupData:model]; / / use systemLayoutSizeFittingSize to obtain high model. CellHeight = [cell. The contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height + 1; }return model.cellHeight;
}
Copy the code
- For example, Autolayout – navigation implementation
# Problems encountered
AutoLayout is a new method just launched after iOS7, because in iOS7 system is not very perfect, often have some bugs, but in iOS8 relatively good processing
-
The most obvious problem is the contentSize of scorllView
-
System constraints are not drawn after they are set, but some time before the last ViewDidApper() function, and after each drawing (e.g., adding a new child control to scorllView, adding a new constraint), ScorllView’s contentOffset and contentSize are both initialized to 0, so they need to be reset each time (if you set contentSize before drawing), or you can use tableView instead of scorllView
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
_scorllView.contentSize = CGSizeMake(200, 200);
}
Copy the code
- Call if you need the frame value immediately after the constraint is set
[view.superview layoutIfNeeded];
Copy the code
And then it’s going to force the update constraint, and then you get the frame, and in iOS8 you just have to put contentSize in there to get a normal scrollView scrolling, but in iOS7 you don’t, notice that.
And if you find any difficult problems, AutoLayout will probably not be suitable for iOS. Therefore, you can search for the word “AutoLayout” directly, instead of searching for the word “navigation”.
- The conflict contentView
- The basic reason for the conflict between the content view and the content view is that the cell’s content view has a systematic constraint (height), and the navigation view will not manage the constraint that it will not generate itself. Therefore, the following attribute Settings should be added when the label imageview is used. Ensure priority to prevent conflicts
[_contentLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
Copy the code
# essays
The reason why I started to write blog, just because, in the process of combing blog, I will let myself know more.
# Finally attached [irregularly updated]
I would like to post a post for you to learn from. I would like to post a video explaining all the navigation I would like to post.
Article on the development of Loin Stringer – introduction to navigation and Its Use
Article on the development of Loin String – “How to design complex Cells using navigation”
Deming Of Starlight Society – Tips on using AutoLayout Frame navigation
The Little Wolf — The Pursuit of Navigation
Interesting Autolayout example – navigation implementation