IOS Auto Layout-uistackpanel and Uigridpanel (iii)

Source: Internet
Author: User

In this article I will continue to explain Uigridpanel.

In the iphone app you can often see some of the nine Gongge layout applications, HTML-developed for this kind of layout should be very familiar. In iOS to implement such a layout method is quite a lot, but I am mainly to explain this time directly through the control to implement, I directly specify a subview in the gridpanel of a row of a column. I even asked the subview to display across multiple rows and columns.

To achieve the above requirements, the Panel must first be required to have the properties of rows and columns, that is, how many rows the panel can be split into. The code is represented as follows:

@interface Uigridpanel:uipanel@property (nonatomic,assign) nsinteger rows; // number of rows, default not 1@property (nonatomic,assign) Nsinteger colums; // number of columns, default not 1 @end

For Subview, you need four properties, row and Colum,rowspan, and Columspan. The code is represented as follows:

@interface UIView (Uigridpanelsubview) // Row Index @property (nonatomic,assign) Nsinteger row; // number of rows spanned @property (nonatomic,assign) Nsinteger RowSpan; // default is 1 // Column Index @property (nonatomic,assign) Nsinteger Colum; // number of columns spanned @property (nonatomic,assign) Nsinteger Columspan; // default is 1 @end

Now that the required properties are there, here's how it's done.

Now that you want to specify a row for a subview (this is assumed to be the first column in the first row, row=colum=1), then we have to have a constraint, the left distance of the Subview panel (assuming the panel's rows=colums=3) The left is the width of the One-third panel, and the right distance of the Subview panel is two-thirds of the panel's width. But this kind of expression method cannot use Nslayoutconstraint to realize, why? Let's start by translating the above description into code, try it.

[nslayoutconstraint constraintwithitem:subview                                 attribute:nslayoutattributeleft relatedBy: Nslayoutrelationequal toitem:self attribute:nslayoutattributeleft Multiplier:1.0 constant: self.frame.size.width/3];

But the panel we do here is self-adapting, which means that when the parent view's height changes, all the subviews aspect should be changed, and the previous statement we handle the panel width as a parameter, and in fact this parameter will change, obviously, blocked.

So let's think about it in a different way, okay?

[nslayoutconstraint constraintwithitem:subview                                 attribute:nslayoutattributeleft relatedBy: Nslayoutrelationequal toitem:self attribute:nslayoutattributewidth Multiplier:1.0/3 Constant:0];

Nslayoutattributeleft and nslayoutattributewidth Two kinds of attributes do not match at all, such a method is not possible.

Another way of thinking, can we make a reference to the Panel's center point? If you are referring to the center point, what is the center point of the subview left distance panel? I'm going to go through the process of figuring out the algorithm.

We first draw a rectangle on the sketch, divide him 3 equal, width position 90, then the width of each column is 30, the center point is 45. So we get a ratio of the left of the first column to the center point of 0/45,

The second column of the left with the center point of the ratio of 30/45, the third column of the left with the center of the ratio of 60/45, sorted out: 0/3,2/3,4/3.

Continue, we draw a rectangle on the sketch, divide him 4 equal, the width locates 100, then each column width is 25, the center point is 50. So we get a ratio, the first column of the left with the center point of the ratio of 0/50, the second column of the left with the center of the ratio is 25/50, the third column of the left with the center point of the ratio of 50/50, the fourth column of the left with the center point of the ratio of 75/50, sorted out: 0/4,2/4,4/ 4,6/4.

Continue, we draw a rectangle on the sketch, divide him 5 equal, the width locates 200, then each column width is 40, the center point is 100. So we get a ratio of the left of the first column to the center point of 0/100, the second column of the left with the center of the ratio of 40/100, the third column of the left with the center point of the ratio of 80/100, the fourth column of the left with the center point of the ratio 120/ 100, the left of the fifth column with the center point than 160/100, sorted out: 0/5,2/5,4/5,6/5,8/5.

Did you see the pattern? The denominator is always the number of equal, and for the column, the denominator is always colums, and the molecule is 2*colum. So we can use Nslayoutconstraint to express it.

    [self addconstraint:[nslayoutconstraint constraintwithitem:subview                                                     attribute:nslayoutattributeleft Relatedby:nslayoutrelationequal toitem:self Attribute:nslayoutattributecenterx multiplier: ((2.0f* Subviewcolum)/self.colums) Constant:margin.left];

Now the algorithm comes out. Then the subsequent processing is simple, including the cross-row and cross-column algorithms can be understood. Directly post the code:

@implementationUIView (Uigridpanelsubview)Char*ConstUiviewrow_str ="Uiviewrowindex";-(void) Setrow: (Nsinteger) row{if(row!=Self.row)        {Objc_setassociatedobject (self, uiviewrow_str, @ (row), Objc_association_retain);    [Self resetconstraints]; }}-(Nsinteger) row{return[Objc_getassociatedobject (Self, uiviewrow_str) integervalue];}Char*ConstUiviewcolum_str ="Uiviewcolumindex";-(void) Setcolum: (Nsinteger) colum{if(colum!=Self.colum)        {Objc_setassociatedobject (self, uiviewcolum_str, @ (colum), objc_association_retain);    [Self resetconstraints]; }}-(Nsinteger) colum{return[Objc_getassociatedobject (Self, uiviewcolum_str) integervalue];}Char*ConstUiviewcolumspan_str ="Uiviewcolumspan";-(void) Setcolumspan: (Nsinteger) columspan{if(columspan!=Self.columspan)        {Objc_setassociatedobject (self, uiviewcolumspan_str, @ (Columspan), objc_association_retain);    [Self resetconstraints]; }}-(Nsinteger) columspan{Nsinteger Columspan=[Objc_getassociatedobject (Self, uiviewcolumspan_str) IntegerValue]; if(columspan<1){        return 1; }    returnColumspan;}Char*ConstUiviewrowspan_str ="Uiviewrowspan";-(void) Setrowspan: (Nsinteger) rowspan{if(rowspan!=Self.rowspan)        {Objc_setassociatedobject (self, uiviewrowspan_str, @ (RowSpan), objc_association_retain);    [Self resetconstraints]; }}-(Nsinteger) rowspan{Nsinteger RowSpan=[Objc_getassociatedobject (Self, uiviewrowspan_str) IntegerValue]; if(rowspan<1)        return 1; returnRowSpan;}@end@implementationUigridpanel@synthesizeRows=_rows;@synthesizecolums=_colums;-(Nsinteger) rows{if(_rows<1){        return 1; }    return_rows;}-(Nsinteger) colums{if(_colums<1){        return 1; }    return_colums;}-(void) Setrows: (Nsinteger) rows{if(_rows!=rows) {_rows=rows;    [Self updateconstraints]; }}-(void) Setcolums: (Nsinteger) colums{if(_colums!=colums) {_colums=colums;    [Self updateconstraints]; }}-(void) Updatesubviewconstraints: (UIView *) subview{if(subview.row>=self.rows) {NSException*e =[nsexception exceptionwithname:@"Uigridpanel Exception"Reason:@"the row index of the child view must be less than the rows of the parent view"Userinfo:nil]; @throwe; }        if(subview.colum>=self.colums) {NSException*e =[nsexception exceptionwithname:@"Uigridpanel Exception"Reason:@"the Colum Index of the child view must be less than the colums of the parent view"Userinfo:nil]; @throwe; } uiedgeinsets margin=Subview.margin; Nsinteger Columspan=Subview.columspan; Nsinteger RowSpan=Subview.rowspan; Nsinteger Subviewrow=Subview.row; Nsinteger Subviewcolum=Subview.colum; if(columspan+subviewcolum>=self.colums) {Columspan=self.colums-Subviewcolum; }        if(rowspan+subviewrow>=self.rows) {RowSpan=self.rows-Subviewrow;                                                     } [Self Addconstraint:[nslayoutconstraint constraintwithitem:subview Attribute:nslayoutattributeleft relatedby:nslayoutrelationequal toitem:self Attribute:nslayoutattributecenterx m Ultiplier: ((2.0f*subviewcolum)/self.colums) Constant:margin.left]; [Self Addconstraint:[nslayoutconstraint constraintwithitem:subview att Ribute:nslayoutattributeright relatedby:nslayoutrelationequal toitem:self Attribute:nslayoutattributecenterx Multiplier: (2.0f* (Subviewcolum+columspan))/self.colums constant:-Margin.right]]; [Self Addconstraint:[nslayoutconstraint constraintwithitem:subview att Ribute:nslayoutattributetop relatedby:nslayoutrelationequal toitem:self Attribute:nslayoutattributecentery Multiplier: ((2.0f*subviewrow)/self.rows) Constant:margin.top]; [Self Addconstraint:[nslayoutconstraint constraintwithitem:subview att Ribute:nslayoutattributebottom relatedby:nslayoutrelationequal toitem:self Attribute:nslayoutattributecentery Multiplier: (2.0f* (Subviewrow+rowspan))/self.rows constant:-Margin.bottom]]; }-(void) Willremovesubview: (UIView *) subview{}-(void) dealloc{[self removeConstraints:self.constraints];}@end

So far, Uigridpanel has been introduced.

The next article will introduce the difficulty of automatic layout-uiscrollview

IOS Auto Layout-uistackpanel and Uigridpanel (iii)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.