Reference: http://blog.sina.com.cn/s/blog_7b9d64af0101edqf.html
Remember, this scene. We are going to arrange multiple identical elements on one interface. You can think of it right away: 1. If you want to use a button, you can uibutton the layout. Such as:
-(void) Showsectionlistbycount: (float) totalcount everycolcount: (float) paramcolcount{
int curnum=1;
int totalrow= Ceilf (totalcount/paramcolcount);//total number of rows
for (int currow=0; currow
for (int curcol=0; curcol//column number
if (totalcount
Return
}
UIButton *btn=[uibutton Buttonwithtype:uibuttontypecustom];
[Btn Setframe:cgrectmake (67+10) *curcol, (30+10) *currow, 67, 30)];
[Btn settitle:[nsstring stringwithformat:@ "%d", curnum]forstate:uicontrolstatenormal];
[Btn setbackgroundimage:[uiimage imagenamed:@ "Btn_tv_n"]forstate:uicontrolstatenormal];
[Btn setbackgroundimage:[uiimage imagenamed:@ "Btn_tv_h"]forstate:uicontrolstatehighlighted];
[Btn Settitlecolor:[uicolor Blackcolor]forstate:uicontrolstatenormal];
[Btn Settitlecolor:[uicolor whitecolor]forstate:uicontrolstatehighlighted];
[Btn addtarget:self Action: @selector (clickcontrolaction:) forcontrolevents:uicontroleventtouchupinside];
[Btn Settag:curnum];
[Self.view ADDSUBVIEW:BTN];
curnum++;
}
}
}
If we want to use a table, then each element can use UITableViewCell to define similar items.
It's easy, because, XCode, we've provided these UI controls for us to use! So, we just need to use!
Well, today's problem is coming! If I want to make a few UI elements that can satisfy myself. Don't worry, that's it:
For example, I want to engage in such an interface!
I think, first of all, it's impossible for Apple to tailor a control for me. And, if I use Apple's default control to write, then I will definitely crash.
In other words, we write each item as a separate UI control. Then, you can populate it according to the data! That would be cool!
Around, a big circle, that is to quote out today to learn, things!
Custom ui!!!
say it, it's bull X. In fact, it is very simple, plainly speaking, is sub-class (rewrite)UIView.
We often rewrite, uibutton,uiimageview,uitableview and so on. Because, maybe we use similar to these existing controls, a little bit of modification can satisfy us.
However, when the entrance is large, we cannot simply inherit from an existing control!
That's a complete rewrite! is the subclass of UIView.
Let's get started!!!
1. Define a UIView subclass.
This doesn't explain!
2. Override the DrawRect method. or override the Layoutsubviews method,
1. DrawRect Method:
-(void) DrawRect: (cgrect) rect
{
Drawing Code
for (int i=0; I<<span style= "color: #2f2fd0" >10; i++) {
UIButton *btn=[uibutton Buttonwithtype:uibuttontypecustom];
[Btn Setframe:cgrectmake (Ten, 10+i*40, 67, 30)];
[Btn setbackgroundimage:[uiimage imagenamed:@ "Btn_n"] forstate:uicontrolstatenormal];
[Btn setbackgroundimage:[uiimage imagenamed:@ "Btn_h"] forstate:uicontrolstatehighlighted];
[Btn addtarget:self Action: @selector (clickcontrolaction:) forcontrolevents:uicontroleventtouchupinside];
[Btn Settag:i];
[Self addsubview:btn];
}
}
2. Layoutsubviews method
-(void) layoutsubviews{
[Super Layoutsubviews];
[Self Setbackgroundcolor:[uicolor clearcolor]];
[_imgpic Setframe:cgrectmake (7, 6, 86, 108)];
[_imgpic setimage:[uiimage imagenamed:[self.dictdata objectforkey:@ "Img_content"]];
[_imgpic.layer Setshouldrasterize:no];
[_imgpic.layer setbordercolor: [[Uicolor Whitecolor] cgcolor];
[_imgpic.layer setborderwidth:1.0];
[[_imgpic layer] setshadowradius:2];
[[_imgpic layer] setshadowopacity:1];
[[_imgpic layer] setshadowcolor:[uicolor Blackcolor]. Cgcolor];
[[_imgpic layer] Setshadowoffset:cgsizemake (0, 1)];
[Self addSubview:self.imgPic];
}
As you can see, both of these methods are available. The specific difference is the difference between the DrawRect method and the Layoutsubviews method.
But, after testing, I found that I should use DrawRect method to finish drawing the interface. Because, if we are using the layoutsubviews method,thelayoutsubviews will be re-executed every time the frame is changed. Obviously unscientific.
On the Internet, I see that most examples use the DrawRect method to redraw the interface. (Drawing interface)
I used the Layoutsubviews method. When frame changes, it is called automatically. (redirect child view)
Choose which method to use as needed!
On the two methods, search on the Internet, summarized as follows:
The layoutsubviews is called in the following cases:
1. Init initialization does not trigger layoutsubviews.
2, Addsubview will trigger layoutsubviews.
3, set the frame of the view will trigger Layoutsubviews, of course, if the frame value has changed before and after the setting.
4, rolling a uiscrollview will trigger layoutsubviews.
5. Rotating screen will trigger the Layoutsubviews event on the parent UIView.
6, changing the size of a uiview will also trigger the parent UIView on the Layoutsubviews event.
7, call Setlayoutsubviews directly.
The drawrect is called in the following cases:
1. If the rect size is not set at UIView initialization, the drawrect will not be automatically called. The DrawRect is dropped after the Controller->loadview, Controller->viewdidload two method. So don't worry. In the controller, The drawrect of the view began to draw. This allows you to set some values in the controller to the view (if some variable values are needed for these view draw).
2, this method is called after calling SizeToFit, so you can call SizeToFit to calculate the size first. The system then automatically calls the DrawRect: method.
3, by setting the Contentmode property value to Uiviewcontentmoderedraw. The drawrect will be called automatically each time the frame is set or changed:.
4. Call Setneedsdisplay directly, or setneedsdisplayinrect: Trigger DrawRect:, but there is a precondition that rect cannot be 0.
Above 1, 2 recommended; 3,4 does not advocate
DrawRect methods use note points:
1, if using UIView drawing, only in the DrawRect: method to obtain the corresponding Contextref and drawing. If obtained in other methods, it gets to a invalidate ref and cannot be used for paint. DrawRect: The method cannot manually display the call, and the system must be automatically tuned by calling Setneedsdisplay or Setneedsdisplayinrect.
2, if using Calayer drawing, can only be drawn in Drawincontext: (similar to DrawRect), or in the corresponding method of delegate. Also call Setneeddisplay and so on indirectly call the above method
3, to real-time paint, can not use Gesturerecognizer, can only use Touchbegan and other methods to drop the Setneedsdisplay real-time refresh screen
3. Customize the initialization method of the UIView.
We often see the Initwithnibname method in Uiviewcontroller:
-(ID) Initwithnibname: (NSString *) Nibnameornil Bundle: (NSBundle *) Nibbundleornil
{
self = [super Initwithnibname:nibnameornil Bundle:nibbundleornil];
if (self) {
Coding
}
return self;
}
This is the initialization method that Xcode defines for us.
Since we want to customize the UIView, it is best to complete the initialization of the subclass UIView according to your business logic:
#pragma mark-initialization incoming data according to business logic, initialize itself
-(ID) Inititemwithfram: (CGRect) frame anddata: (nsmutabledictionary *) paramdata{
self = [super Initwithframe:frame];
if (self) {
Initialization code
_dictdata=[[nsmutabledictionary alloc] init];
_imgpic=[[uiimageview alloc] init];
_imgcover=[[uiimageview alloc] init];
_btnclick=[[uibutton alloc] init];
_btndel=[[uibutton alloc] init];
_lbltips=[[uilabel alloc] init];
_lblname=[[uilabel alloc] init];
}
Self.dictdata=paramdata;
return self;
}
+ (ID) inititemwithframe: (CGRect) frame anddata: (nsmutabledictionary *) paramdata{
Wtvtvcollectionitem *tmpinstance=[[wtvtvcollectionitem alloc] initItemWithFram:frameandData:paramData];
return tmpinstance;
}
In this way, the initialization is possible:
Nsmutablearray *items = [Nsmutablearray array];
[Items Addobject:[wtvtvcollectionitem Inititemwithframe:cgrectmake (ten, Ten, and Anddata:dict]];
[Items Addobject:[wtvtvcollectionitem Inititemwithframe:cgrectmake (ten, Ten, and Anddata:dict]];
[Items Addobject:[wtvtvcollectionitem Inititemwithframe:cgrectmake (ten, Ten, and Anddata:dict]];
4. Add some animations for UIView
Animation is the soul of UI manipulation! Give the animation effect, it looks like God.
Add animations, generally also in 2 ways:
1. Override the UIView method to animate the call.
# pragma mark-Overrides the Removefromsuperview method of the parent class and, when deleted, uses the corresponding animation effect
-(void) Removefromsuperview {
[UIView animatewithduration:0.2 animations:^{
Self.alpha = 0.0;
[Self Setframe:cgrectmake (self.frame.origin.x+50, self.frame.origin.y+50, 0, 0)];
[_btndel setframe:cgrectmake (0, 0, 0, 0)];
}completion:^ (BOOL finished) {
[Super Removefromsuperview];
}];
}
2. Add the animated object directly on the UIView element
-(void) enableediting {
if (Self.isineditingmode = = YES)
Return
Set to edit state
Self.isineditingmode = YES;
[_btndel Sethidden:no];
Start shaking animation
Catransform3d transform;
Get an integer between 0 and X-1
if (Arc4random ()% 2 = = 1)
Transform = catransform3dmakerotation (-0.08, 0, 0, 1.0);
Else
Transform = catransform3dmakerotation (0.08, 0, 0, 1.0);
Cabasicanimation *animation = [cabasicanimation animationwithkeypath:@ "transform"];
Animation.tovalue = [Nsvalue valuewithcatransform3d:transform];
animation.autoreverses = YES;
Animation.duration = 0.1;
Animation.repeatcount = 10000;
Animation.delegate = self;
[Self layer] addanimation:animation forkey:@ "Wiggleanimation"];
[(wtvtvsprintboard*) self.delegate Enableeditingmode];
}
5. Sub-UIView interaction
How to link the operation!? That is, outside the control, we operate on our custom controls?!
There are also 2 ways to do this:
1. Message
2. Agent
Summarize:
I think, I too much will be thinking about it, because the business needs are different, the custom requirements of the control is also different, so, can not be fixed with concrete! However, the idea is figured out, knowing the principle, we can play our wisdom, create the ever-changing control!
Hope to help you!!!
[iOS] Custom UI