Drop-down list box implementation
I. Implementation framework 1
Ii. Implement Root View 1
Iii. Implementation of dropdownlist Class 2
4. Some Improvements 6
Cocoa touch does not provide drop-down box controls because they provide uipickerview. Why do I need to use a drop-down box that has become one of Windows standard controls? "This is not an apple Experience"-"Apple Experience" advocates such opposition. However, as programmers transferred from the Windows development platform, they only need one reason to refute: uipickerview is too large, and there is no drop-down box control to save screen space. This is the case. Put a uipickerview, which is more than enough to put three drop-down boxes.
I. Implementation Framework
1. Create a window-based-application.
2. Create a New uiviewcontroller: rootviewcontroller. Add self. view = [[uiviewalloc] initwithframe in its loadview method:
[[Uiscreenmainscreen] bounds];
3. Modify appdelegate, add the following two sentences, and import the related classes so that the application can load a rootviewcontroller at startup:
Rootviewcontroller * root = [[rootviewcontrolleralloc] init];
[Windowaddsubview: Root. View];
Ii. Implement the Root View
1. Add several text boxes to the Root View to simulate the drop-down list box (implemented later) and add code to the loadview method:
// One textfield
Uitextfield * tF = [[uitextfieldalloc] initwithframe:
Cgrectmake (144, 73,140, 30)];
TF. borderstyle = uitextborderstyleroundedrect;
[Self. viewaddsubview: TF];
[Tfrelease];
// Two textfields
TF = [[uitextfieldalloc] initwithframe:
Cgrectmake (144,129,140, 30)];
TF. borderstyle = uitextborderstyleroundedrect;
[Self. viewaddsubview: TF];
[Tfrelease];
The running effect is as follows:
2. Replace uitextfield with dropdownlist. Next, we are going to implement this dropdownlist by ourselves.
Iii. Implementation of the dropdownlist class
1. Create the uiview subclass dropdownlist.
2. We are going to use a text input box and a tableview control to implement this drop-down box. Declare the following statement in the header file and pay attention to the corresponding @ synthesize statement:
@ Interfacedropdownlist: uiview {
Uitextfield * textfield; // text input box
Nsarray * List; // drop-down list data
Boolshowlist; // whether to display the drop-down list
Uitableview * listview; // drop-down list
Cgrectoldframe, newframe; // rectangle of the entire control (including before and after the drop-down)
Uicolor * linecolor, * listbgcolor; // The border color and background color of the drop-down box
Cgfloatlinewidth; // The Border width of the drop-down box.
Uitextborderstyleborderstyle; // text box border Style
}
@ Property (nonatomic, retain) uitextfield * textfield;
@ Property (nonatomic, retain) nsarray * List;
@ Property (nonatomic, retain) uitableview * listview;
@ Property (nonatomic, retain) uicolor * linecolor, * listbgcolor;
@ Property (nonatomic, assign) uitextborderstyleborderstyle;
-(Void) drawview;
@ End
3. initialize the variable in the initwithframe method and call the drawview Drawing Control:
If (Self = [superinitwithframe: frame]) {
// Data in the default drop-down list
List = [[nsarrayalloc] initwithobjects: @ "1", @ "2", @ "3", @ "4", nil];
Borderstyle = uitextborderstyleroundedrect;
Showlist = no; // the drop-down list is not displayed by default.
Oldframe = frame; // initial size of the widget when no pull-down is performed
// When the drop-down box is displayed, the control size is calculated.
Newframe = cgrectmake (frame. Origin. X, frame. Origin. Y, frame. Size. Width, frame. Size. Height * 5 );
Linecolor = [uicolorlightgraycolor]; // the border line of the default list is gray.
Listbgcolor = [uicolorwhitecolor]; // the background color of the default list box is white.
Linewidth = 1; // The Border width of the default list is 1.
// Set the background color to transparent, otherwise there will be a Black edge
Self. backgroundcolor = [uicolorclearcolor];
[Selfdrawview]; // call a method to draw a widget
}
Returnself;
4. First draw a text box in the drawview method:
// Text box
Textfield = [[uitextfieldalloc]
Initwithframe: cgrectmake (0, 0,
Oldframe. Size. Width,
Oldframe. Size. Height)];
Textfield. borderstyle = borderstyle; // you can specify the border style of the text box.
[Selfaddsubview: textfield];
Run the program for testing. However, when we click the dropdownlist control input box, the keyboard will automatically pop up and we need to block it. After the above Code, add:
// Add the text box's touch Event Response
[Textfieldaddtarget: selfaction: @ selector (dropdown)
Forcontrolevents: uicontroleventalltouchevents];
Then implement the dropdown method:
-(Void) dropdown {
[Textfieldresignfirstresponder];
}
Now, the keyboard will not pop up automatically.
5. Add code to the drawview method to draw the tableview control:
// Drop-down list
Listview = [[uitableviewalloc] initwithframe:
Cgrectmake (linewidth, oldframe. Size. height + linewidth,
Oldframe. Size. Width-linewidth * 2,
Oldframe. Size. Height * 4-linewidth * 2)];
Listview. datasource = self;
Listview. Delegate = self;
Listview. backgroundcolor = listbgcolor;
Listview. separatorcolor = linecolor;
Listview. Hidden =! Showlist; // The listview is hidden at the beginning, and then displayed or hidden based on the value of showlist.
[Selfaddsubview: listview];
[Listviewrelease];
Now we must implement the tableview protocol (do not forget to declare the uitableviewdatasource and uitableviewdelegate protocols in the header file ):
# Pragma mark listviewdatasource method and delegate Method
-(Nsinteger) tableview :( uitableview *) Table numberofrowsinsection :( nsinteger) Section {
Returnlist. count;
}
-(Uitableviewcell *) tableview :( uitableview *) tableviewcellforrowatindexpath :( nsindexpath *) indexpath {
Staticnsstring * cellid = @ "listviewid ";
Uitableviewcell * cell = [tableviewdequeuereusablecellwithidentifier: cellid];
If (cell = nil ){
Cell = [[[uitableviewcellalloc] initwithstyle: uitableviewcellstyledefault
Reuseidentifier: cellid] autorelease];
}
// Text tag
Cell. textlabel. Text = (nsstring *) [listobjectatindex: indexpath. Row];
Cell. textlabel. font = textfield. Font;
Cell. selectionstyle = uitableviewcellselectionstylegray;
Return cell;
}
-(Cgfloat) tableview :( uitableview *) tableviewheightforrowatindexpath :( nsindexpath *) indexpath {
Returnoldframe. Size. height;
}
// When selecting a row from the drop-down list, set the value in the text box to hide the drop-down list
-(Void) tableview :( uitableview *) tableviewdidselectrowatindexpath :( nsindexpath *) indexpath {
// Nslog (@ "select ");
Textfield. Text = (nsstring *) [listobjectatindex: indexpath. Row];
// Nslog (@ "textfield. Text = % @", textfield. Text );
[Selfsetshowlist: No];
}
Setshowlist is the setter method of the showlist variable. This method hides or displays the drop-down Box Based on the given parameters. Use the following method to access the showlist variable:
-(Bool) showlist {// setshowlist: No indicates hiding, and setshowlist: Yes indicates displaying
Returnshowlist;
}
-(Void) setshowlist :( bool) B {
Showlist = B;
Nslog (@ "showlist is set ");
If (showlist ){
Self. Frame = newframe;
} Else {
Self. Frame = oldframe;
}
Listview. Hidden =! B;
}
Run the program and click the text box. The drop-down box is not displayed. Don't worry. There is no relevant code for our dropdown method:
If (showlist) {// If the drop-down box is displayed, nothing will be done
Return;
} Else {// If the drop-down list is not displayed
// Put the dropdownlist in front to prevent the drop-down box from being hidden by other controls
[Self. superviewbringsubviewtofront: Self];
[Selfsetshowlist: Yes]; // display the drop-down list
}
Run the program and click the text box. The drop-down list is displayed. However, tableview has no border:
To add a border to the drop-down box, we need to implement the following methods:
// Add a border for tableview
-(Void) drawrect :( cgrect) rect {
// Nslog (@ "% @", rect );
Cgcontextrefctx = uigraphicsgetcurrentcontext ();
Cgrectdrawrect;
If (showlist ){
Cgcontextsetstrokecolorwithcolor (CTX, [linecolorcgcolor]);
Drawrect = listview. frame;
Cgcontextstrokerect (CTX, drawrect );
// Cgcontextstrokerectwithwidth (CTX, drawrect, linewidth );
} Else {
Return;
}
// [Selfdrawlistborder: CTX: drawrect];
}
This method is called when you receive the setneedsdisplay method. Therefore, you need to send the setneedsdisplay message when the drop-down list is displayed. Send the setneedsdisplay message at the end of the setshowlist method:
[Selfsetneedsdisplay]; // call drawrect to repaint
The running effect is as follows:
If we want to display our own data in the list, we can assign values to the list attribute after constructing the dropdownlist:
Dropdownlist * tF = [[dropdownlistalloc] initwithframe:
Cgrectmake (144, 73,140, 30)];
TF. borderstyle = uitextborderstyleroundedrect;
TF. textfield. placeholder = @ "Please enter the contact information ";
Nsarray * arr = [[nsarrayalloc] initwithobjects: @ "phone", @ "email", @ "Mobile Phone", nil];
TF. List = arr;
[Arrrelease];
[Self. viewaddsubview: TF];
[Tfrelease];
The running effect is as follows:
Iv. Some Improvements
1. Use nsdictionary as the model data
Because the drop-down box option generally consists of two parts of data: display text and data, it is more appropriate to use a dictionary type consisting of "key-value" pairs to represent the data model of the drop-down box. Therefore, we modify the dropdownlist to the nsdictionary type:
Nsstring * data; // variable that stores the key value of the selected item
Nsdictionary * List; // drop-down list data
Nsarray * allkeys; // All keys
Zookeeper
@ Property (nonatomic, retain) nsstring * data;
-(Void) setlist :( nsdictionary *) val;
Zookeeper
@ Synthesize data
Zookeeper
List = [[nsdictionarydictionarywithobjectsandkeys:
@ "Marketing Department", @ "1", @ "Administrative Department", @ "2", nil] retain];
Allkeys = [list. allkeysretain];
Zookeeper
-(Void) setlist :( nsdictionary *) Val {
List = val;
Allkeys = Val. allkeys;
Allkeys. Retain;
[Listviewreloaddata]; // refresh textview display
Textfield. Text = @ ""; // clear the text box content. The text box content cannot be different from the content in the drop-down list.
}
Modify the code in both the tableview data source method and delegation method:
-(Uitableviewcell *) tableview :( uitableview *) tableviewcellforrowatindexpath :( nsindexpath *) indexpath {
Zookeeper
// Obtain the keys and values in the dictionary
Nsstring * skey = [list. allkeysobjectatindex: indexpath. Row];
Nsstring * sval = (nsstring *) [listobjectforkey: skey];
// Text tag
Cell. textlabel. Tag = skey;
Cell. textlabel. Text = sval;
[Skeyrelease];
[Svalrelease];
Zookeeper
}
-(Void) tableview :( uitableview *) tableviewdidselectrowatindexpath :( nsindexpath *) indexpath {
// Obtain the keys and values in the dictionary
Data = [allkeysobjectatindex: indexpath. Row];
Textfield. Text = (nsstring *) [listobjectforkey: Data];
[Selfsetshowlist: No];
}
Now we only construct a dropdownlist object and do not need to modify any attributes. The result is as follows:
When you select a drop-down option, the text in the text box changes.
2. Define the protocol and extend it through delegation
It is obviously not enough to display the list for users to choose without performing any action. We can define a delegate attribute and assign the selected action to the delegate.
First, you need to define the work to be delegated in the header file, that is, the Protocol:
@ Protocoldropdownlistdelegate
@ Required
-(Void) selected :( nsstring *) K displaylabel :( nsstring *) V;
@ End
Second, define an ID attribute in the header file:
ID <dropdownlistdelegate> delegate; // delegate, post-processing when selected drop-down items
Zookeeper
@ Property (nonatomic, assign) ID <dropdownlistdelegate> delegate;
Then in the implementation section @ synthesize delegate;
In the-(void) tableview: didselectrowatindexpath: method, add:
If (delegate! = Nil ){
[Delegateperformselector: @ selector (selected: displaylabel :)
Withobject: datawithobject: textfield. Text];
}
Return to rootviewcontroller and add <dropdownlistdelegate> after the class name in interface.
Add droplist. Delegate = self in the loadview method;
Finally, the methods defined in the Implementation Protocol are as follows:
-(Void) selected :( nsstring *) K displaylabel :( nsstring *) V {
Nslog (@ "% @: % @", K, V );
}
Run the program and select the drop-down list. The delegate method (Protocol method) is called and the background output is as follows:
15:13:05. 104 dropdownbox [3048: 207] 1: Marketing Department
15:13:07. 288 dropdownbox [3048: 207] 2: Administration Department
15:13:09. 153 dropdownbox [3048: 207] 1: Marketing Department
15:13:11. 371 dropdownbox [3048: 207] 2: Administration Department
Classes are extended by delegation and Protocol. Compared with extensions by subclass, classes are obviously more flexible and code is more dispersed.