1.One is cgfloat.it ' s a floating point number. All floating point numbers that has the to does with drawing on the screen or getting touch events or whatever is Cgfloats.thi s might be a double. It might is just a regular floating point number. Not only using CGFloat to specify positions no screens and all the thing s,but if you ' re going to be multiplying or adding Numbers to things is on screens to recalculate new things,all you want to do all that in the cgfloat domain. So your ' re going to has a lot of properties and the local variables that is cgfloats when you ' re doing screen stuff. ( 2.then there ' s a c-struct called Cgpoint.that has just got the elements in it. X and Y.that ' s an X and y position. And there ' s cgsize which is just a struct with width and height which be both cgfloats also. And that ' s just specifying a width and height. And then there ' s cgrect which are c-struct with those and the other of the CG structs in them. Cgpoint and cgsize that specifies an origin and a width and height for a REctangle. ( 3.and) The reason for, that is, the can be rotated. And if a view is rotated you can see that the rectangle this contains it might be much bigger. Right? Because It's a diamond shape that it had to contain. Bottom Line was understand that frame was a rectangle containing you in your Superview ' s coordinate system,bounds are the rec Tangle you use the draw when you ' re drawing in your own code in your view. (11:00am) 4.so Let's talk about the context. Mostly you don ' t has to worry about the context because you ' re going to use uibezierpath.but a context means where am I Drawi ng in terms of-am I drawing on screens right now? Am I drawing off screen,in some bitmap? Am I creating a PDF file out of what I ' m drawing? Am I drawing to printer? So, the context part of it. For normal Drawing,uikit Sets the this context up for your before it calls Drawrect.and then once your ' re in Drawrect,context are Ready to go. (18:00) 5.and Remember if we create views,things that go in The view Camp,they want to be as generic as POSSIBLE,AS reusable as possible. (47:00) 6.so i ' m doing setneedsdisplay just to make sure,if anyone changes the rank or the suit or the faceup-ness of My thing,i tell the system I need to be redrawn. (49:00) 7.and i ' m going to has that rounded rect is as big as Possible,so I specify
Self.boundsAs the rectangle to draw this roundedrect in.
Self.bounds is my coordinate system. Its width and height are the amount of space I have on screen to draw in. (50:00) 8.first thing I ' m gonna to does this RO Udedrect actually,is i ' m gonna clip to It,because I don ' t want to draw outside that Roundedrect.okay? That's the interior of my card,so I ' m just going to clip to that. It also lets me do something like this. Uicolor Whitecolor,set My fill color,and then I can just use this C function,uirectfill,and you specify a rectangle,self.b Ounds. Okay,this just fills this rectangle. And this was going to make a big rectangle,but this clip was going to keep the white of this on the inside of that Roundedre Ct. So it's not a going to draw the white on the corners up there. (52:00) 9.i ' m also going to do, Contentmode = Uiviewcontentmoderedraw.remember I told you if my bounds ever Change,i want to get my drawrect called. and then,really Importantly,i want to make sure I does this on awakefromnib.because,in fact,in this demo,i am going to be CR Eating this VieW in a storyboard. I ' m not doing alloc init in It,so this is how I am going to get set up. (53:00) 10.hierarchical:a view have only one Superview-(UIView *) Superview. But can has many (or zero) subviews-(Nsarray *) subviews. Subview order (in Subviews array matters): those later in the array is on top of those earlier. A view can clip its subviews-it bounds or not. 11.the top of this hierarchy for your MVC is the @property view! Uiviewcontroller ' s @property (strong,nonatomic) UIView *view. This is the view whose bounds would be changed when autorotation happens,for example. This is the view of the would programmatically add subviews to. All your MVC's view ' s UIView ' s eventually has this View as their parent (it's at the top). It is automatically hooked up for your when you are drag out a View Controller in xcode. 12.yes,you might want to override UIView ' s designated initializer. But you'll also want to set up stuff in Awakefromnib.this are because initwithframe:is not called for a UivieW coming out of a storyboard! But Awakefromnib is. Typical code ...
-(void) setup{...} -(void) awakefromnib{[self setup];} -(ID) initwithframe: (cgrect) arect{ = [Super Initwithframe:arect]; [Self setup]; return
13.Views has 3 properties related to their location and size.
// your view ' s internal drawing space ' s origin and size
The Bounds property is a inside your view own implementation.
It's up to your implementation as-to-interpret the meaning of bounds.origin.
@property Cgpoint Center; // The center of your view in your Superview ' s coordinate space@property cgrect frame; // a rectangle in your superview ' s coordinate space which entirely contains your view ' s bounds.size
14.How Do you create a UIView in code (i.e. not in Xcode)? Just Use Alloc and initWithFrame: (UIView ' s designated initializer). Can also use init (frame'll be Cgrectzero). Example:
CGRect labelrect = CGRectMake (20 , 20 , 50 , 30 ); UILabel *label = [[UILabel alloc]initwithframe:labelrect];labe.text = @ " Hello! "; [Self.view Addsubview:label]; // note self.view!
15.so How do I implement my drawrect:? Use the Core Graphics framework directly (a C api,not object-oriented). Or we can use the object-oriented Uibezierpath class. Core Graphics Concepts:get A context to draw into (IOS would prepare one each time your drawrect:is called) Create paths of Lines,arcs,etc.) Set colors,fonts,textures,line widths,lineups,etc. Stroke or fill the above-created paths. Uibezierpath:do all of the above,but capture it with an object. Then ask the object to the stroke or fill the created. 16.the context determines where your drawing goes:screen,o Ffscreen bitmap,pdf. Printer.for normal Drawing,uikit sets up the current context for you. But it's only valid during this particular call to DrawRect:. A New one is the set up for your each time drawrect:is called. So never caches the current graphics context in drawrect:to use later! How to get the This magic context? Uibezierpath draws into the current context,so you don't need to get it if using that. But if you ' re calling COre Graphics C functions directly,you ' ll need it (it's an argument to them). The following C function inside your drawrect:method to get the current graphics context.
Cgcontextref context = Uigraphicsgetcurrentcontext ();
17.Define a Path:
//Begin the path:Uibezierpath *path =[[Uibezierpath alloc]init];//Move around,add lines or arcs to the path:[Path Movetopoint:cgpointmake ( the,Ten)]; [Path Addlinetopoint:cgpointmake ( the, Max)]; [Path Addlinetopoint:cgpointmake (Ten, Max)];//Close The path (connects)[Path Closepath];//Not strictly required but triangle won ' t has all 3 slides otherwise//Now, the path has been created,we can stroke/fill it. (Actually,noting has been drawn yet,we ' ve just created the Uibezierpath).[[Uicolor Greencolor]setfill]; [[Uicolor Redcolor]setstroke]; [Path fill]; [path stroke];
18.Can also set graphics state:e.g.
path.linewidth = 2.0//line width in points (not pixels)and draw rounded rects,ovals,etc.
Uibezierpath *roundedrect =*oval = [Uibezierpath bezierpathwithovalinrect: (cgrect) bounds]; [Roundedrect stroke]; [Oval fill];
You can use a uibezierpath to "clip" your drawing:
[Roundedrect Addclip]; // This would clip all drawing to be inside the Roundedrect
19.What happens when overlap? As mentioned Before,subviews list order determine ' s in front. Lower ones (earlier in subviews array) can "show through" transparent views on top of them. Also,you can hide a view completely by setting hidden.
@property (nonatomic) BOOL Hidden;myview.hidden = YES; // View is not being in screen and would not handle events
Uncommon as you might think. On a small screen,keeping it de-cluttered by hiding currently unusable Also This can is used to swap, and the depending on state. 20.Special Considerations for defining drawing ' subroutines ' What if you wanted to has a utility method that draws Somethi Ng? You don ' t want this utility method to mess and the graphics state of the The calling method. Use Save and restore context functions.
-(void ) Drawgreencircle: (CGCONTEXTREF) txt{cgcontextsavegstate (ctxt); [[Uicolor Greencolor] setfill]; // draw my circle Cgcontextrestoregstate (ctxt);} -(void = Uigraphicsgetcurrentcontext (); [[Uicolor Redcolor] setfill]; // do some stuff [self Drawgreencircle:context]; // do more stuff and expect fill color Red }
21.We can use a UILabel as a subview to draw text in our view,but there is certainly occasions where We want to draw text In our DrawRect:. To draw in Drawrect:,use nsattributedstring.
Nsattributedstring *text = ...; [Text drawatpoint: (Cgpoint) p]; // Nsattributedstring instance method added by UIKit.
How much space would a piece of text would take the up when drawn?
Cgsize textSize = [text size]; Another UIKit nsattributedstring instance method
You might is disturbed that there is drawing methods in Foundation (a Non=ui framework!). These nsattributedstring methods is defined in UIKit via a mechanism called categories. Categories is an objective-c-in-a-to-add methods to an existing class without subclassing. 22.Drawing Images:uiimageview is a like UILabel for Images. But again,occasionally your want to draw a image in your drawrect:. Create a UIImage object from a file in your Resources folder
UIImage *image = [UIImage imagenamed:@ "foo.jpg"]
Or create one from a named file or from raw data:
UIImage *image = [[UIImage alloc]initwithcontentsoffile: (NSString **image = [[UIImage alloc]initwithdata: ( NSDate *) ImageData];
Or you can even create one by drawing with Cgcontext functions:
Uigraphicsbeginimagecontext (gcsize); // draw with Cgcontext functions UIImage *myimage = uigraphicsgetimagefromcurrentcontext (); Uigraphicsendimagecontext ();
Now blast the UIImage's bits into the current graphics context:
UIImage *image = ...; [Image drawatpoint: (Cgpoint) p]; // p is upper left of the image [Image drawinrect: (CGRect) r]; // Scales the image to fit in R [Image drawaspatterninrect: (CGRect) patrect]; // tiles the image into Patrect
Aside:you can get a PNG or JPG data representation of UIImage
NSData *jpgdata = uiimagejpegrepresentation ((UIImage **pngdata = uiimagepngrepresentation ((UIImage *) myimage );
23.By Default,when your UIView ' s bounds change,there is no redraw. Instead,the "Bits" of your view would be stretched or squished or moved. Often This isn't what you want ... Luckily,there is a UIView @property to control this! It can is set in Xcode.
@property (nonatomic) Uiviewcontentmode Contentmode;These content modes move the bits of your drawing to this location ... Uiviewcontentmode{left,right,top,right,bottomleft,bottomright,topleft,topright}these modes stretch the bits of your Drawing ... Uiviewcontentmodescale{tofill,aspectfill,aspectfit}//bit stretching/shrinkingthis content Mode calls Drawrect:to Redraw everything when the bounds changes ... Uiviewcontentmoderedraw//it is quite often it is uiviewcontentmodescaletofill (stretch the B Its to fill the bounds) 24.gestures was recognized by the class Uigesturerecognizer.this class is "abstract". We only actually use "concrete subclasses" of it. There is sides to using a gesture recognizer:1.adding a gesture recognizer to a UIView to ask it to recognize that GE Sture.2.providing the implementation of a method to "handle" this gesture when it happens. Usually #1 is done by a controllerthough occasionally a UIView would do it to itself if it just doesn ' t make sense without That gesture. Usually #2 is PROvided by the UIView itselfbut it would isn't being unreasonable for the Controller to do it. Or for the Controller to decide it wants to handle a gesture differently than the view does. 25.adding a gesture reco Gnizer to a UIView from a Controller
-(void ) Setpannableview: (UIView *) Pannableview // maybe This was a setter in a Controller {_pannableview = Pannableview; Uipangesturerecognizer *pangr = [[Uipangesturerecognizer Alloc]initwithtarger :p Annableview Action: @selector (pan:)]; [Pannableview Addgesturerecognizer:pangr];}
Uipangesturerecognizer is a concrete subclass of Uigesturerecognizer that recognizes "panning" (moving something around wit H your finger). There are,of course,other concrete subclasses (for swipe,pinch,tap,etc.) Note that we are specifying the view itself as the "target to handle a" pan gesture when it is recognized. Thus The view would be both the recognizer and the handler of the gesture. The UIView does not has to handle the gesture. It could be,for Example,the Controller that handles it. The view would generally handle gestures to modify what the view is drawn. The Controller would has to handle gestures this modified the Model. @selector (pan:) is the action method, which would be Sen T to the target (the Pannableview) during the handling of the recognition of this gesture. If we don ' t do this,then even though the Pannableview implements Pan:,it would never get called because we would has Neve R added this gesture recognizer to the view's list of gestures that it recognizes. Think of this as "turning tHe handling of this gesture on ". Only UIView instances can recognize a gesture (because uiviews handle all touch input). But Ant object can tell a UIView to recognize a gesture (by adding a recognizer to the UIView). And any object can handle the recognition of a gesture (by being the target of the gesture's action). 26.how do we imp Lement the target of a gesture recognizer? Each concrete class provides some methods. For Example,uipangesturerecognizer provides 3 methods:
-(Cgpoint) Translationinview: (UIView *) Aview; -(Cgpoint) Velocityinview: (UIView *) Aview; -(void) Settranslation: (cgpoint) Translation InView: (UIView *) Aview;
Also,the Base Class,uigesturerecognizer provides this @property:
@property (readonly) uigesturerecognizerstate state;Gesture recognizers sit around in the state Possible until they start to be recognized. Then they either go to recognized (for discrete gestures like a tap) Or they go to began (for continuous gestures like a pan) At any time,the state can change to Failed (so watch out for that) If the gesture are continuous,it ' ll move on to the Changed And eventually the Ended statecontinuous can also go to Cancelled state (if the recognizer realizes it's not this gesture After all)
[Lecture Notes] Stanford University Open class: IOS 7 App Development Lecture7