第五課內容: 自動旋轉、 Protocols、 手勢識別、一個自定義UIView的Demo
1、自動旋轉
- - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation
- {
- return UIInterfaceOrientationIsPortrait(orientation); // only support portrait
- return YES; // support all orientations
- return (orientation != UIInterfaceOrientationPortraitUpsideDown); // anything but
- }
三種控制方式:
- @property (nonatomic) UIViewContentMode contentMode;
- UIViewContentMode{Left,Right,Top,Right,BottomLeft,BottomRight,TopLeft,TopRight}
- UIViewContentModeScale{ToFill,AspectFill,AspectFit} // bit stretching/shrinking
- @property (nonatomic) CGRect contentStretch;
2、協議procotol
- @protocol Foo <Other, NSObject> // implementors must implement Other and NSObject too
- - (void)doSomething; // implementors must implement this (methods are @required by default)
- @optional
- - (int)getSomething; // implementors do not have to implement this
- - (void)doSomethingOptionalWithArgument:(NSString *)argument; // also optional
- @required
- - (NSArray *)getManySomethings:(int)howMany; // back to being “must implement”
- @property (nonatomic, strong) NSString *fooProp; // note that you must specify strength
- @end
可以定義在自己的頭文件裏,也可以定義在其他類的頭文件中。
- #import “Foo.h” // importing the header file that declares the Foo @protocol
- @interface MyClass : NSObject <Foo> // MyClass is saying it implements the Foo @protocol
- ...
- @en
- id <Foo> obj = [[MyClass alloc] init];
- @property (nonatomic, weak) id <Foo> myFooProperty; // properties too!
委託幾乎都是weak的,因爲被設置爲委託的對象通常都是委託對象的所有者或創建者。
- @protocol UIScrollViewDelegate
- @optional
- - (UIView *)viewForZoomingInScrollView:(UIScrollView *)sender;
- - (void)scrollViewDidEndDragging:(UIScrollView *)sender willDecelerate:(BOOL)decelerate;
- @end
- @interface UIScrollView : UIView
- @property (nonatomic, weak) id <UIScrollViewDelegate> delegate;
- @end
- @interface MyViewController : UIViewController <UIScrollViewDelegate>
- @property (nonatomic, weak) IBOutlet UIScrollView *scrollView;
- @end
- @implementation MyViewController
- - (void)setScrollView:(UIScrollView *)scrollView {
- _scrollView = scrollView;
- self.scrollView.delegate = self; // compiler won’t complain
- }
- - (UIView *)viewForZoomingInScrollView:(UIScrollView *)sender { return ... };
- @end
3、手勢識別
如何獲得觸摸事件呢?
- - (void)setPannableView:(UIView *)pannableView
- {
- _pannableView = pannableView;
- UIPanGestureRecognizer *pangr =
- [[UIPanGestureRecognizer alloc] initWithTarget:pannableView action:@selector(pan:)];
- [pannableView addGestureRecognizer:pangr];
- }
UIPangestureRecognizer的三個方法:
- - (CGPoint)translationInView:(UIView *)aView;
- - (CGPoint)velocityInView:(UIView *)aView;
- - (void)setTranslation:(CGPoint)translation inView:(UIView *)aView;
手勢識別的狀態機
- @property (readonly) UIGestureRecognizerState state;
pan:是什麼樣的呢:
- - (void)pan:(UIPanGestureRecognizer *)recognizer
- {
- if ((recognizer.state == UIGestureRecognizerStateChanged) ||
- (recognizer.state == UIGestureRecognizerStateEnded)) {
- CGPoint translation = [recognizer translationInView:self];
- // move something in myself (I’m a UIView) by translation.x and translation.y
- // for example, if I were a graph and my origin was set by an @property called origin
- self.origin = CGPointMake(self.origin.x+translation.x, self.origin.y+translation.y);
- [recognizer setTranslation:CGPointZero inView:self];
- }
- }
其他實例的手勢:
4、一個幸福笑臉的Demo:
內容介紹:
- #import <UIKit/UIKit.h>
- @interface HappinessViewController : UIViewController
- @property (nonatomic) int happiness; // 0 is sad; 100 is very happy
- @end
- #import "HappinessViewController.h"
- #import "FaceView.h"
- @interface HappinessViewController() <FaceViewDataSource>
- @property (nonatomic, weak) IBOutlet FaceView *faceView;
- @end
- @implementation HappinessViewController
- @synthesize happiness = _happiness;
- @synthesize faceView = _faceView;
- - (void)setHappiness:(int)happiness
- {
- _happiness = happiness;
- [self.faceView setNeedsDisplay]; // any time our Model changes, redraw our View
- }
- - (void)setFaceView:(FaceView *)faceView
- {
- _faceView = faceView;
- // enable pinch gestures in the FaceView using its pinch: handler
- [self.faceView addGestureRecognizer:[[UIPinchGestureRecognizer alloc] initWithTarget:self.faceView action:@selector(pinch:)]];
- [self.faceView addGestureRecognizer:[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleHappinessGesture:)]]; // gesture to modify our Model
- self.faceView.dataSource = self;
- }
- - (void)handleHappinessGesture:(UIPanGestureRecognizer *)gesture
- {
- if ((gesture.state == UIGestureRecognizerStateChanged) ||
- (gesture.state == UIGestureRecognizerStateEnded)) {
- CGPoint translation = [gesture translationInView:self.faceView];
- self.happiness -= translation.y / 2;
- [gesture setTranslation:CGPointZero inView:self.faceView];
- }
- }
- - (float)smileForFaceView:(FaceView *)sender
- {
- return (self.happiness - 50) / 50.0; // translate Model for View
- }
- - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
- {
- return YES; // support all orientations
- }
- @end
- #import <UIKit/UIKit.h>
- @class FaceView; // forward declaration for use in @protocol
- @protocol FaceViewDataSource
- - (float)smileForFaceView:(FaceView *)sender;
- @end
- @interface FaceView : UIView
- @property (nonatomic) CGFloat scale;
- - (void)pinch:(UIPinchGestureRecognizer *)gesture; // resizes the face
- // set this property to whatever object will provide this View's data
- // usually a Controller using a FaceView in its View
- @property (nonatomic, weak) IBOutlet id <FaceViewDataSource> dataSource;
- @end
- #import "FaceView.h"
- @implementation FaceView
- @synthesize dataSource = _dataSource;
- @synthesize scale = _scale;
- #define DEFAULT_SCALE 0.90
- - (CGFloat)scale
- {
- if (!_scale) {
- return DEFAULT_SCALE; // don't allow zero scale
- } else {
- return _scale;
- }
- }
- - (void)setScale:(CGFloat)scale
- {
- if (scale != _scale) {
- _scale = scale;
- [self setNeedsDisplay]; // any time our scale changes, call for redraw
- }
- }
- - (void)pinch:(UIPinchGestureRecognizer *)gesture
- {
- if ((gesture.state == UIGestureRecognizerStateChanged) ||
- (gesture.state == UIGestureRecognizerStateEnded)) {
- self.scale *= gesture.scale; // adjust our scale
- gesture.scale = 1; // reset gestures scale to 1 (so future changes are incremental, not cumulative)
- }
- }
- - (void)setup
- {
- self.contentMode = UIViewContentModeRedraw; // if our bounds changes, redraw ourselves
- }
- - (void)awakeFromNib
- {
- [self setup]; // get initialized when we come out of a storyboard
- }
- - (id)initWithFrame:(CGRect)frame
- {
- self = [super initWithFrame:frame];
- if (self) {
- [self setup]; // get initialized if someone uses alloc/initWithFrame: to create us
- }
- return self;
- }
- - (void)drawCircleAtPoint:(CGPoint)p withRadius:(CGFloat)radius inContext:(CGContextRef)context
- {
- UIGraphicsPushContext(context);
- CGContextBeginPath(context);
- CGContextAddArc(context, p.x, p.y, radius, 0, 2*M_PI, YES); // 360 degree (0 to 2pi) arc
- CGContextStrokePath(context);
- UIGraphicsPopContext();
- }
- - (void)drawRect:(CGRect)rect
- {
- CGContextRef context = UIGraphicsGetCurrentContext();
- CGPoint midPoint; // center of our bounds in our coordinate system
- midPoint.x = self.bounds.origin.x + self.bounds.size.width/2;
- midPoint.y = self.bounds.origin.y + self.bounds.size.height/2;
- CGFloat size = self.bounds.size.width / 2;
- if (self.bounds.size.height < self.bounds.size.width) size = self.bounds.size.height / 2;
- size *= self.scale; // scale is percentage of full view size
- CGContextSetLineWidth(context, 5.0);
- [[UIColor blueColor] setStroke];
- [self drawCircleAtPoint:midPoint withRadius:size inContext:context]; // head
- #define EYE_H 0.35
- #define EYE_V 0.35
- #define EYE_RADIUS 0.10
- CGPoint eyePoint;
- eyePoint.x = midPoint.x - size * EYE_H;
- eyePoint.y = midPoint.y - size * EYE_V;
- [self drawCircleAtPoint:eyePoint withRadius:size * EYE_RADIUS inContext:context]; // left eye
- eyePoint.x += size * EYE_H * 2;
- [self drawCircleAtPoint:eyePoint withRadius:size * EYE_RADIUS inContext:context]; // right eye
- #define MOUTH_H 0.45
- #define MOUTH_V 0.40
- #define MOUTH_SMILE 0.25
- CGPoint mouthStart;
- mouthStart.x = midPoint.x - MOUTH_H * size;
- mouthStart.y = midPoint.y + MOUTH_V * size;
- CGPoint mouthEnd = mouthStart;
- mouthEnd.x += MOUTH_H * size * 2;
- CGPoint mouthCP1 = mouthStart;
- mouthCP1.x += MOUTH_H * size * 2/3;
- CGPoint mouthCP2 = mouthEnd;
- mouthCP2.x -= MOUTH_H * size * 2/3;
- float smile = [self.dataSource smileForFaceView:self];
- if (smile < -1) smile = -1;
- if (smile > 1) smile = 1;
- CGFloat smileOffset = MOUTH_SMILE * size * smile;
- mouthCP1.y += smileOffset;
- mouthCP2.y += smileOffset;
- CGContextBeginPath(context);
- CGContextMoveToPoint(context, mouthStart.x, mouthStart.y);
- CGContextAddCurveToPoint(context, mouthCP1.x, mouthCP2.y, mouthCP2.x, mouthCP2.y, mouthEnd.x, mouthEnd.y); // bezier curve
- CGContextStrokePath(context);
- }
- @end
容芳志 (http://blog.csdn.net/totogo2010)
本文遵循“署名-非商業用途-保持一致”創作公用協議
原文地址:http://blog.csdn.net/totogo2010/article/details/8222166