"iOS Development-48" Nine Gongge layout case: Self-active layout, dictionary to model use, ID and instancetype differences, xib repeated view usage and nib relationship

Source: Internet
Author: User

This nine Gongge case:


(1) Import app.plist and various picture material, it is convenient to develop. The same is true in real-world development.


(2) Import the array in the plist.

--because App.plist is finally an array in this case, the array is a dictionary. So we need an array type to accept this plist file.

--We use the previously mastered in the variable getter to delay loading data.

#import "ViewController.h" @interface Viewcontroller () @property (Nonatomic,strong) Nsarray *arr1; @end @implementation viewcontroller-(void) viewdidload {    self.arr1;    [Super Viewdidload];} -(Nsarray *) arr1{    if (_arr1==nil) {        nsstring *path=[[nsbundle mainbundle]pathforresource:@ "App.plist" OfType : nil];        _arr1=[nsarray Arraywithcontentsoffile:path];        NSLog (@ "%@", _arr1);    }    return _ARR1;} @end
The output is:

        {        icon = "icon_00";        Name = "\u5929\u5929\u9177\u8dd1";    },        {        icon = "icon_01";        Name = "\u5168\u6c11\u98de\u673a\u5927\u6218";    },  ...


Icon is followed by the name of the icon, name is also named after name, just Chinese is converted to Unicode form, a Chinese character is a \u****.

(3) Calculation of nine lattice

The key is to use/and the% operation to get the rows and columns of the element, note that the% sign operation can not be cgfloat before and after the conversion is better than the int type.

--cgfloat is actually a collection of float and double. All the places with float and double were almost able to use CGFloat. will be based on the current system to resolve their own initiative, assuming that the 32-bit system, then float, assuming that the 64-bit system, then resolved to double.

-(void) Viewdidload {    //defines the total number of columns, each nine Gongge the width of the high    int totalcolumns=3;    CGFloat appw=90;    CGFloat apph=100;    Define horizontal and Vertical spacing    cgfloat marginx= (SELF.VIEW.FRAME.SIZE.WIDTH-TOTALCOLUMNS*APPW)/(totalcolumns+1);    CGFloat marginy=20;        Initialize and load one uiview for (int index=0; index<self.arr1.count; index++) According to the number of data in the arr1.    {        //Calculate the app in a few rows        int row=index/totalcolumns;        int col=index%totalcolumns;        Create UIView        UIView *appview=[[uiview alloc]init];        Based on some calculations, determine the location of the different UIView        Appview.frame=cgrectmake (marginx+col* (MARGINX+APPW), 30+row* (MARGINY+APPH), APPW, APPH);        Appview.backgroundcolor=[uicolor Redcolor];        [Self.view Addsubview:appview];    }        [Super Viewdidload];    Do any additional setup after loading the view, typically from a nib.}

(4) Add a Uiimageview, Uilabel and UIButton to each appview. Add it directly to the for loop, which creates the UIView *appview and creates it in the same way.

-In the Uiimageview, the picture used to get the name of the picture, this can be stored in the plist inside, we put the corresponding dictionary in the _ARR1 to use it.

The point is that the font size of the UIButton cannot be set directly, but instead is set using the UIButton Titlelabel in the child view. (since UIButton actually encapsulates two sub-view controls, one is the Uilabel *titlelabel of the loaded text, the Uiimageview *imageview of a picture)

    for (int index=0; index<self.arr1.count; index++) {//Calculate this app in a few rows of several columns of int row=index/totalcolumns;        int col=index%totalcolumns;        Create UIView UIView *appview=[[uiview Alloc]init];        Based on some calculations, determine the location of the different UIView Appview.frame=cgrectmake (marginx+col* (MARGINX+APPW), 30+row* (MARGINY+APPH), APPW, APPH);//        Appview.backgroundcolor=[uicolor Redcolor];                [Self.view Addsubview:appview];                According to the index to get plist each dictionary data nsdictionary *appdic=_arr1[index];        Add child controls to Appview icon//dictionary to get inside the icon name Uiimageview *appicon=[[uiimageview Alloc]init];        CGFloat iconw=65;        CGFloat iconh=65;        CGFloat iconx= (APPW-ICONW)/2;        CGFloat icony=0;        Appicon.frame=cgrectmake (IconX, Icony, Iconw, Iconh);        Appicon.image=[uiimage imagenamed:appdic[@ "icon"];                [Appview Addsubview:appicon];        Add child controls to Appview label UILabel *applabel=[[uilabel Alloc]init]; CGFloat labelW=APPW;        CGFloat labelh=20;        CGFloat labelx= (APPW-LABELW)/2;        CGFloat Labely=icony+iconh;        Applabel.frame=cgrectmake (LabelX, labely, Labelw, LABELH);        applabel.text=appdic[@ "Name"];        Applabel.textalignment=nstextalignmentcenter;        Applabel.font=[uifont systemfontofsize:14];                [Appview Addsubview:applabel];        Add child controls to Appview button UIButton *appbtn=[[uibutton alloc]init];        CGFloat btnw=65;        CGFloat btnh=26;        CGFloat btnx= (APPW-BTNW)/2;        CGFloat Btny=labely+labelh;        Appbtn.frame=cgrectmake (Btnx, Btny, BTNW, BTNH);        [appbtn settitle:@ "Download" forstate:uicontrolstatenormal];        Appbtn.titlelabel.font=[uifont systemfontofsize:14];        [Appbtn setbackgroundimage:[uiimage imagenamed:@ "Buttongreen"] forstate:uicontrolstatenormal];        [Appbtn setbackgroundimage:[uiimage imagenamed:@ "buttongreen_highlighted"] forstate:uicontrolstatenormal];    [Appview ADDSUBVIEW:APPBTN]; }

(5) most important : dictionary to model

The disadvantage of using a dictionary: you need to use the key value to adjust and set the data, sometimes error, although the ability to improve with macro variables, but the more fatal to write the wrong key value, no error prompts.

Model: Strictly called model data. The core is that we think of the dictionary as an object, a few data in the dictionary, we are converted to several properties of the object, we call and set the data directly "object. Property".

So, we need to create a class that is dedicated to storing data, which is often called model classes.

In this example, create a Jiugongge class, declare 2 variables in. h, and 2 initialization methods (the specification has 2 initialization methods, in fact the core is one, the other is implemented by the first one).

#import <Foundation/Foundation.h> @interface jiugongge:nsobject@property (nonatomic,copy) NSString *name;@ Property (nonatomic,copy) NSString *icon;-(instancetype) Initwithjiugongge: (Nsdictionary *) dic;+ (instancetype) Jiugonggewith: (Nsdictionary *) dic; @end

Implemented in JIUGONGGE.M (note writing, memory):

#import "JiuGongGe.h" @implementation jiugongge-(Instancetype) Initwithjiugongge: (nsdictionary *) dic{    if (self=[ Super Init]) {        self.name=dic[@ "name"];        self.icon=dic[@ "icon"];    }    return self;} + (Instancetype) Jiugonggewith: (nsdictionary *) dic{    return [[Jiugongge alloc]initwithjiugongge:dic];} @end

In fact, our small title is "dictionary to model", that is, simply convert the dictionary into a model (object), the original dictionary is stored in the array, and then through the array [index] to call the dictionary, and now the model (object) is still stored in the array. So we need to improve the Getter method for the array: (Note: You need to #import "JiuGongGe.h" in VIEWCONTROLLER.M, because you want to instantiate the object)

-(Nsarray *) arr1{    if (_arr1==nil) {        nsstring *path=[[nsbundle mainbundle]pathforresource:@ "App.plist" OfType : nil];        Nsarray *tmparr=[nsarray Arraywithcontentsoffile:path];        Nsmutablearray *muarr1=[[nsmutablearray Alloc]init];        For (Nsdictionary *dict in Tmparr) {            Jiugongge *jiugognge=[jiugongge jiugonggewith:dict];            [MuArr1 Addobject:jiugognge];        }        _arr1=muarr1;    }    return _ARR1;}

In the viewdidload for loop, the use of the object can be used in the place. property to invoke the data:

        According to the index to get each object, here Appdic name is not changed, or use the dictionary before the variable, see not very accustomed to        Jiugongge *appdic=_arr1[index];                Add child controls to Appview icon        ...        Appicon.image=[uiimage ImageNamed:appDic.icon];                Add child controls to Appview label        Applabel.text=appdic.name;

(6) Jiugonggewith: (Nsdictionary *) dic; Improvement of initialization method

-The name of the class used inside can be replaced with self. Since this class is prevented from having subclasses, it is assumed that the subclass calls Jiugonggewith: (Nsdictionary *) dic; When called to the parent class, the name of the parent class is written, and the initialization result is an object of the parent class, not the object of the child class. So with self, who calls on the object whose initialization is initialized.


(7) Description of ID type and instancetype

--instancetype and ID are all universal pointers.

--ios recommends that we use Instancetype to replace the ID. Although the official very many return values of the Init method are also IDs.

The advantage of using an ID is that the ID is a universal pointer, and we don't have to worry about the problem of its return value type mismatch.

The disadvantage of using ID: It is also because it is a universal pointer, we can accept the return value with random pointers, for example NSString *str1=****,nsarray *arr1=****, this code is written out to not error. But it may not be the type of return value we need.

The advantage of using instancetype is that assuming that our return value is an object, then you accept the return value with the above two random pointers, it will have a warning warning, we will use the class object Jiugongge *jiugognge=***, will not be warned.

--instancetype can only be used on the return value type and cannot be used as an ID in the number of parameters.


(8) Reduce code with xib graphical layout

The difference between Xib and storyboard is that storyboard is a descriptive narrative of the entire program interface, and Xib is used to describe the local repetitive interface.

For example, in this case there are 12 applications, each application view is the same, can be implemented with Xib, and then xib loaded in.

Creation of Xib (with empty):


Layout in Ourxib:

--For Uiimageview and Uilabel, set the tag to 10 and 20 respectively for easy invocation.

--Drag the control to the interface, change the size, Uiimageview need to set size to freeform ability to resize.


Once the ourxib is set up, it can be called:

--Except for resources outside the picture, it needs to be called with [NSBundle Mainbundle].

--the method of calling the Xib file is the Loadnibnamed method of the Mainbundle.

    for (int index=0; index<self.arr1.count; index++) {        //calculate this app in a few rows of several columns of        int row=index/totalcolumns;        int col=index%totalcolumns;                Get each object according to the index        Jiugongge *appdic=_arr1[index];        Nsarray *xibarr=[[nsbundle mainbundle]loadnibnamed:@ "Ourxib" Owner:nil Options:nil];        UIView *xibview=[xibarr Lastobject];        Xibview.frame=cgrectmake (marginx+col* (MARGINX+APPW), 30+row* (MARGINY+APPH), APPW, APPH);        Uiimageview *imgview2= (Uiimageview *) [Xibview viewwithtag:10];        Imgview2.image=[uiimage ImageNamed:appDic.icon];                UILabel *label2= (UILabel *) [Xibview viewwithtag:20];        Label2.text=appdic.name;        Add to the main view        [Self.view Addsubview:xibview];    }

(9) What is the relationship between the Xib file and the nib file?

The--xib file is something that our developers saw when they developed it;

-The Xib file is converted to a nib file when executed on the user's phone.

We are able to view it in the sandbox generated by iOS simulator.

--Unable to find the repository path, directly with NSLog (@ "%@", [NSBundle mainbundle), and print out the path.

Find out that the repository does have a ourxib.nib file, and the Xib file does turn into a nib file.



"iOS Development-48" Nine Gongge layout case: Self-active layout, dictionary to model use, ID and instancetype differences, xib repeated view usage and nib relationship

Related Article

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.