At the beginning

  • This is a sub-chapter. For the whole article, see the Learning Diary of Zero-based iOS development

summary

  • The arrangement is a little messy. These knowledge points are quite scattered. I don’t have many places to use in my current project
  • There is a bit of trouble implementing the event, and I feel there is no need to clean it up at the moment, I will talk about QAQ when I have time

CALayer

The actual use

  • It is more straightforward to style the control
  • Controls the animation

Basic usage

  • Set styles, mostly rounded corners
UIView *redView = [UIView new]; redView.frame = CGRectMake(100, 100, 100, 100); redView.backgroundColor = [UIColor redColor]; / / set the border redView. Layer. BorderWidth = 10; / / border color redView. Layer. BorderColor = [UIColor grayColor]. CGColor; / / shadow redView. Layer. ShadowOffset = CGSizeMake (4, 4); / / migration to the upper left corner for the origin. RedView layer. The shadowColor = [UIColor blueColor]. CGColor; redView.layer.shadowRadius = 10; / / shadow radius redView. Layer. ShadowOpacity = 1; / / set the transparency / / rounded redView. Layer. The cornerRadius = 20; / / not beyond the scope of layer shows that beyond the scope of the shadow can be eliminated redView. Layer. MasksToBounds = YES; Redview.layer. bounds = CGRectMake(0, 0, 200, 200); //position defaults to center redView.layer.position = CGPointMake(0, 0); // Set the contents __bridge id redView.layer.contents = (__bridge id)([UIImage imageNamed:@"Gin_1"].cgImage); [self.view addSubview:redView];Copy the code
  • Set the animation
Rotate / / / / to a certain point of view Angle, x, y, z self. Layer. The transform = CATransform3DMakeRotation (M_PI_4, 1, 0, 0); Self.layer. transform = CATransform3DRotate(self.layer.transform, M_PI_4, 0, 0, 1); Self.layer. transform = CATransform3DScale(self.layer.transform, 0.5, 0.5, 0.1); self.layer.transform = CATransform3DScale(self.layer.transform, 0.5, 0.1); Self. layer.transform = CATransform3DTranslate(self.layer.transform, 10, 0, 10); self.layer.transform = CATransform3DTranslate(self.layer.transform, 10, 0);Copy the code

An implicit animation

  • Custom layer
CALayer *layer = [CALayer new]; layer.backgroundColor = [UIColor redColor].CGColor; layer.position = CGPointMake(200, 200); layer.bounds = CGRectMake(0, 0, 100, 100); layer.contents = (__bridge id)[UIImage imageNamed:@"Gin_1"].CGImage; // Add [self.view.layer addSublayer:layer];Copy the code
  • CALayer has its own implicit animation, that is, when changing the layer control, there will be a certain change, automatically generated animation effect
  • The root control layer means that the layer obtained directly from the created control is not implicitly animated
*t = touches. AnyObject; CGPoint p = [t locationInView:t.view]; Self.layer. bounds = CGRectMake(0, 0, 200, 200); The self. The layer. The opacity = 0.5; self.layer.position = p;Copy the code
  • Disable implicit animation
*t = touches. AnyObject; CGPoint p = [t locationInView:t.view]; Self.layer. bounds = CGRectMake(0, 0, 200, 200); The self. The layer. The opacity = 0.5; // Disable implicit animation [CATransaction begin]; // Open things [CATransaction setDisableActions:YES]; // Disable implicit animation self.layer.position = p; [CATransaction commit]; / / submitCopy the code

The core of animation

The actual use

  • Move the control

Basic usage

Basic animation

  • Operate directly on the Layer property
//1. Create CABasicAnimation* anim = [CABasicAnimation new]; Anim. keyPath = @"position.x"; //2. // anim.fromValue = @(10); // anim.toValue = @(300); // add // im.byValue = @(10); BeginTime = CACurrentMediaTime() + 3; // Start anim.fromValue = @300; // End value anim.toValue = @400; anim.duration = 3; /** kCAFillModeForwards // After 3 seconds of animation start, move from the initial position to X =300, move to 400 kCAFillModeForwards // After 3 seconds of animation start, move straight to the starting position of animation, such as up to x=300, 3 seconds later to 500, KCAFillModeBoth // including the above two kCAFillModeRemoved default return to the original position */ // default return to the original position, Anim. fillMode = kcafillmodeforward; anim.removedOnCompletion = NO; //3. AddAnimation (who does the animation) [self.layer addAnimation:anim forKey:nil];Copy the code

Keyframe animation

  • Layer moves to the frames that are laid down
CAKeyframeAnimation *anim = [CAKeyframeAnimation new]; anim.keyPath = @"position"; NSValue *v1 = [NSValue valueWithCGPoint:CGPointMake(100, 100)]; NSValue *v2 = [NSValue valueWithCGPoint:CGPointMake(150, 100)]; NSValue *v3 = [NSValue valueWithCGPoint:CGPointMake(100, 150)]; NSValue *v4 = [NSValue valueWithCGPoint:CGPointMake(150, 150)]; Anim. values = @[v1,v2,v3,v4]; / / / / path animation UIBezierPath * path = [UIBezierPath bezierPathWithArcCenter: CGPointMake (150, 150) radius:100 startAngle:0 endAngle:2 * M_PI clockwise:1]; // anim.path = path.CGPath; // time anim.duration = 3; Anim. repeatCount = INT_MAX; [self.layer addAnimation:anim forKey:nil];Copy the code

Group of animation

  • Add multiple animation effects at once
CAAnimationGroup *group = [CAAnimationGroup new]; // Rotate CABasicAnimation *anim = [CABasicAnimation new]; anim.keyPath = @"transform.rotation"; anim.byValue = @(2 * M_PI * 10); CAKeyframeAnimation *anim1 = [CAKeyframeAnimation new]; anim1.keyPath = @"position"; / / path animation UIBezierPath * path = [UIBezierPath bezierPathWithArcCenter: CGPointMake (150, 150) radius:100 startAngle:0 endAngle:2 * M_PI clockwise:1]; anim1.path = path.CGPath; group.animations = @[anim, anim1]; group.duration = 3; group.repeatCount = INT_MAX; [self.layer addAnimation:group forKey:nil];Copy the code

Animated transitions

  • The view of the ferry
  • You need to set the animation mode and direction
  • The following is implemented in conjunction with gestures, which are also organized below
- (IBAction)imageChange:(UISwipeGestureRecognizer *)sender { NSLog(@"UISwipeGestureRecognizer"); CATransition *anim = [CATransition new]; 'fade',' moveIn', 'push' and' reveal'. Defaults to 'fade' Some of them work and some of them don't // @cube ", @suckeffect ", @oglflip ", @rippleEffect ", @pagecURL ", @pageUncurl ", @CamerairishollowOpen ", @Camerairishollowc lose" anim.type = @"push"; if (sender.direction == UISwipeGestureRecognizerDirectionRight) { self.imageName --; if (self.imageName == 0) { self.imageName = 6; } // Direction anim.subtype = kCATransitionFromLeft; NSLog(@"UISwipeGestureRecognizerDirectionRight"); } else if (sender.direction == UISwipeGestureRecognizerDirectionLeft) { self.imageName ++; if (self.imageName == 7) { self.imageName = 1; } anim.subtype = kCATransitionFromRight; NSLog(@"UISwipeGestureRecognizerDirectionLeft"); } self.imageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%ld", self.imageName]]; Duration = 1; anim.duration = 1; [self.imageView.layer addAnimation:anim forKey:nil]; } - (void)viewDidLoad { [super viewDidLoad]; self.imageName = 1; }Copy the code

Gesture recognition

Implementation steps

  1. Creating a gesture object
  2. Add a gesture to a view
  3. Implementing gesture methods

knock

  • Gestures method
- (void)tap:(UITapGestureRecognizer *)sender
{
    NSLog(@"UITapGestureRecognizer");
}
Copy the code
  • implementation
/** @property (nonatomic) NSUInteger numberOfTapsRequired; @property (nonatomic) NSUInteger numberOfTouchesRequired API_UNAVAILABLE(tVOs); UITapGestureRecognizer *tap = [UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)]; tap.numberOfTapsRequired = 2; tap.numberOfTouchesRequired = 2; // Add a gesture to a view [self.imageView addGestureRecognizer:tap];Copy the code

Long press

  • Gestures method
- (void) longPress sender: (UILongPressGestureRecognizer *) {/ / UIGestureRecognizerStateEnded loosen / / UIGestureRecognizerStateBegan press the minimum time the if (sender. State = = UIGestureRecognizerStateChanged) { NSLog(@"UILongPressGestureRecognizer"); }}Copy the code
  • implementation
/** @property (nonatomic) NSTimeInterval minimumPressDuration; // Response time @property (nonatomic) CGFloat allowableMovement; @property(nonatomic, readOnly) UIGestureRecognizerState state; / / state judge * / UILongPressGestureRecognizer * longPress = [[UILongPressGestureRecognizer alloc] initWithTarget: self action:@selector(longPress:)]; [self.imageView addGestureRecognizer:longPress]; longPress.minimumPressDuration = 1; longPress.allowableMovement = 100;Copy the code

Swept gently

  • Gestures method
-(void)swipe:(UISwipeGestureRecognizer *)sender { if (sender.direction == UISwipeGestureRecognizerDirectionLeft) { NSLog(@"UISwipeGestureRecognizer --- right"); } else if (sender.direction == UISwipeGestureRecognizerDirectionRight) { NSLog(@"UISwipeGestureRecognizer --- left"); }}Copy the code
  • implementation
/** @property(nonatomic) UISwipeGestureRecognizerDirection direction; // Direction */ UISwipeGestureRecognizer */ UISwipeGestureRecognizer */ UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)]; [self.imageView addGestureRecognizer:swipe]; UISwipeGestureRecognizer *swipe1 = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)]; swipe1.direction = UISwipeGestureRecognizerDirectionLeft; [self.imageView addGestureRecognizer:swipe1];Copy the code

rotating

  • Gestures method
-(void)rotation:(UIRotationGestureRecognizer *)sender { self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, sender.rotation); Rotation = 0; NSLog(@"UIRotationGestureRecognizer"); }Copy the code
  • implementation
/** @property (nonatomic) CGFloat rotation; / / * / rotation Angle rotation UIRotationGestureRecognizer * = [[UIRotationGestureRecognizer alloc] initWithTarget: self action:@selector(rotation:)]; [self.imageView addGestureRecognizer:rotation];Copy the code

kneading

  • Gestures method
-(void)pinch:(UIPinchGestureRecognizer *)sender { self.imageView.transform = CGAffineTransformScale(self.imageView.transform, sender.scale, sender.scale); Sender.scale = 1; NSLog(@"UIPinchGestureRecognizer"); }Copy the code
  • implementation
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)];
[self.imageView addGestureRecognizer:pinch];
Copy the code

Drag and drop

  • Gestures method
-(void)pan:(UIPanGestureRecognizer *)sender
{
    CGPoint p = [sender translationInView:sender.view];
    self.imageView.transform = CGAffineTransformTranslate(self.imageView.transform, p.x, p.y);
    [sender setTranslation:CGPointZero inView:sender.view];
    NSLog(@"UIPanGestureRecognizer");
    NSLog(@"%.f", sender.view.frame.origin.x);
}
Copy the code
  • implementation
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
[self.imageView addGestureRecognizer:pan];
Copy the code

Multiple gestures are added simultaneously

  • throughUIGestureRecognizerDelegateProxy method implementation
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)];
tap.numberOfTapsRequired = 1;
tap.numberOfTouchesRequired = 2;
tap.delegate = self;
[self.imageView addGestureRecognizer:tap];

UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotation:)];
[self.imageView addGestureRecognizer:rotation];
rotation.delegate = self;

UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)];
[self.imageView addGestureRecognizer:pinch];
pinch.delegate = self;
Copy the code
  • Resolving gesture Conflicts
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}
Copy the code

The event

  • The first responder indicates that the current user interacts with the object
  • The responder chain, if the first responder doesn’t handle it, will go up, find the superview, and so on, all the way to the top view, and then UIWindow and UIApplication, and if there’s no response at all, the event will be discarded

The event type

  • UIEventType
UIEventTypePresses UIEventTypeTouches UIEventTypeMotion, shaking UIEventTypeRemoteControl, remote control events, press UIEventTypeScroll, Scroll UIEventTypeHover, finger on it UIEventTypeTransform,Copy the code
  • UIEventSubtype Subevent type, which is segmented for remote control events
Available in iPhone OS 3.0 UIEventSubtypeNone = 0, // for UIEventTypeMotion, Available in the iPhone OS 3.0 UIEventSubtypeMotionShake = 1, / / a for UIEventTypeRemoteControl, The available in iOS 4.0 UIEventSubtypeRemoteControlPlay = 100, UIEventSubtypeRemoteControlPause = 101, UIEventSubtypeRemoteControlStop = 102, UIEventSubtypeRemoteControlTogglePlayPause = 103, UIEventSubtypeRemoteControlNextTrack = 104, UIEventSubtypeRemoteControlPreviousTrack = 105, UIEventSubtypeRemoteControlBeginSeekingBackward = 106, UIEventSubtypeRemoteControlEndSeekingBackward = 107, UIEventSubtypeRemoteControlBeginSeekingForward = 108, UIEventSubtypeRemoteControlEndSeekingForward = 109,Copy the code

Touch events

  • Monitor touch function

Touches parameters

Window Window where the touch is located View View of the touch tapCount Number of clicks in a short time timestamp Time when the touch event changed, timestamp format (seconds) Phase Touch phaseCopy the code
  • Touch the stage
UITouchPhaseBegan, 0 UITouchPhaseMoved, 1 UITouchPhaseStationary, 2 fingers touching but not moving UITouchPhaseEnded, 3 UITouchPhaseCancelled, 4Copy the code

Touches get coordinates

  • Touches the current coordinate with parameters as the coordinate system
UITouch *t = touches.anyObject; / / below is based on the parent coordinate system CGPoint p = [t locationInView: self. Superview]; // CGPoint p1 = [t locationInView:self]; NSLog(@"%@", NSStringFromCGPoint(p)); NSLog(@"%@", NSStringFromCGPoint(p1));Copy the code
  • The coordinates of the last point of the touch with the parameter coordinate system
UITouch *t = touches.anyObject;
CGPoint p = [t previousLocationInView:self];
Copy the code

Touch event state

  • Cancelled when a touch is cancelled (e.g. interrupted by a call)
  • The other three are literal
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { } - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { } - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { }  - (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { }Copy the code

Shaking event

  • Relevant methods
- (void)motionBegan:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event;
- (void)motionEnded:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event;
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event;
Copy the code
  • Implemented by Device-> Shake simulation
  • In the view
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event { if (motion == UIEventSubtypeMotionShake) { Self.backgroundcolor = [UIColor colorWithRed:(float)arc4random_uniform(256) / 255.0) Green :(float) arc4random_Uniform (256) / 255.0) Blue :(float) arc4random_Uniform (256) / 255.0) alpha:1.0]; NSLog(@"UIEventSubtypeMotionShake"); } } - (BOOL)canBecomeFirstResponder { return YES; }Copy the code
  • In the vc
- (void)viewDidLoad {
    [super viewDidLoad];
    
    [UIApplication sharedApplication].applicationSupportsShakeToEdit = YES;
}
- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [self.myView becomeFirstResponder];
}
- (void)viewDidDisappear:(BOOL)animated {
    [self.myView resignFirstResponder];
}
Copy the code