iOS-imitation sticker rolling (physical simulation)

Guide reading

Simply use OC to write a small ball rolling effect;
It's like a balance ball.


Worship rolling

Get to the Topic - (Sensors)

Sensor is an induction detection device, which has been widely used in smart phones to detect the information around the device. Different types of sensors have different information.

Sensors in iOS


sensor

Introduction to CoreMotion Framework

CoreMotion. Framework is a core motion framework in iOS. CoreMotion is a framework specially dealing with Motion. It contains two parts of accelerometer and gyroscope. Before iOS 4, accelerometer was collected by UIAccelerometer class. Accelerometer is determined by three coordinate axes. The most common operation device of users moves, shakes mobile phone (shakes one), and tilts hand. Machines can be set up to detect, accelerometers can detect linear changes, gyroscopes can better detect deflection actions, according to the user's actions to make corresponding actions, iOS simulator can not simulate the above actions, real-time debugging needs the developer's account.

2. CoreMotion Data Acquisition

There are two main ways to get data in CoreMotion:

  • Push mode:
    Provide a thread manager, NSOperationQueue, and a callback Block, which CoreMotion automatically calls back every time the sampled data arrives for processing. In this case, the operations in the Block will be executed in your own main thread.

  • Pull mode, in this way, you have to take the initiative to ask for data like CMMotion Manager, which is the latest sampling data.

1. Pull method

- (void)pull{
    //Initialization of global management objects
    CMMotionManager *manager = [[CMMotionManager alloc] init];
    self.motionManager = manager;
    //Judging whether the accelerometer is unavailable or not
    if ([manager isAccelerometerAvailable] && [manager isAccelerometerActive]){
        //Tell the manager that the update frequency is 100 Hz
        manager.accelerometerUpdateInterval = 1 / 60;
        //Start updating, background threads start running. This is the Pull way.
        [manager startAccelerometerUpdates];
    }
    //Accelerometer data acquisition and processing
    CMAccelerometerData *newestAccel = self.motionManager.accelerometerData;
    NSLog(@"X = %.04f",newestAccel.acceleration.x);
    NSLog(@"Y = %.04f",newestAccel.acceleration.y);
    NSLog(@"Z = %.04f",newestAccel.acceleration.z);
}

2.Push method

//Judging whether an accelerometer is available
if([_motionManager isAccelerometerAvailable]) {
    // Setting Accelerometer Frequency
    [_motionManager setAccelerometerUpdateInterval:1 / 60];
    //Sampling data at the beginning
    [_motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
        NSLog(@"%f---%f",accelerometerData.acceleration.x,accelerometerData.acceleration.y);
    }];
} else{
    NSLog(@"Equipment does not support accelerometers");
}

The gyroscope is the same as the accelerometer.

iOS UIDynamicAnimator

Several Behaviors of Physics

  1. Adsorption Behavior of UIAttachment Behavior

  2. UICollision Behavior Collision Behavior

  3. Gravity Behavior of UIGravityBehavior

  4. UIPush Behavior Thrust Behavior

  5. UISnapBehavior Captures Behavior

UIAttachment Behavior Adsorption

    // 1 can follow anchor 2 can item and item
    self.attach = [[UIAttachmentBehavior alloc] initWithItem:self.view1 attachedToItem:self.view2];
    self.attach.length = 100;// distance
    self.attach.damping = 0.3;// Damping coefficient (hindering change)
    self.attach.frequency = 0.5;// Vibration Frequency, (Variable Velocity)

//    self.attach.anchorPoint = CGPointMake(100, 100);

    [self.animator addBehavior:self.attach];
// 2. They maintain interaction under the action of other animations.

UICollision Behavior Collision

# pragma mark-collision
-  (UICollisionBehavior *)collision {

    if (_collision == nil) {

        _collision = [[UICollisionBehavior alloc] init];
       //Reference boundary
        _collision.translatesReferenceBoundsIntoBoundary = YES;
      //All things collide
        _collision.collisionMode = UICollisionBehaviorModeEverything;
        [self.animator addBehavior:_collision];
    }

    return _collision;

}
// 1 bezierPath boundary
    UIBezierPath *bezierPath1 = [UIBezierPath bezierPathWithArcCenter:CGPointMake(CGRectGetWidth(self.view.bounds)/2, CGRectGetHeight(self.view.bounds)) radius:CGRectGetWidth(self.view.bounds)/2 startAngle:0 endAngle:2*M_PI clockwise:YES];
    [self.collision addBoundaryWithIdentifier:@"bezierPath1" forPath:bezierPath1];

    // 2 point1 - point2 boundary
    [self.collision addBoundaryWithIdentifier:@"point1_point2" fromPoint:CGPointMake(0, 300) toPoint:CGPointMake(CGRectGetWidth(self.view.bounds), 400)];

UIGravityBehavior Gravity

# pragma mark - gravity
-  (UIGravityBehavior *)gravity {

    if (_gravity == nil) {

        _gravity = [[UIGravityBehavior alloc] init];
//        _gravity.magnitude = 1.0;
        [self.animator addBehavior:_gravity];
    }

    return _gravity;

}

UIPush Behavior Thrust

    self.push = [[UIPushBehavior alloc] init];

    self.push.active = YES;// Activation or not
    self.push.angle = M_PI/4;// direction
    self.push.magnitude = 0.5;// Power

//    self.push.pushDirection = CGVectorMake(1, 2);//Vector

UISnapBehavior capture

UISnapBehavior * snapbehavior = [[UISnapBehavior alloc] initWithItem:self.imageview snapToPoint:self.view.center]; 
snapbehavior.damping = 0.65;
[self.animator addBehavior:snapbehavior];

Dynamic Properties of UIDynamicItemBehavior

# pragma mark - kinetic properties
-  (UIDynamicItemBehavior *)dynamic {

    if (_dynamic == nil) {

        _dynamic = [[UIDynamicItemBehavior alloc] init];
        _dynamic.friction = 0.2;
        _dynamic.elasticity = 0.8;
        _dynamic.density = 0.2;
        _dynamic.allowsRotation = YES;
        _dynamic.resistance = 0;
        [self.animator addBehavior:_dynamic];
    }

    return _dynamic;

}

Specific application

    Adding various behaviors to the view
    [self.dynamic addItem:ballView];
    [self.collision addItem:ballView];
    [self.gravity addItem:ballView];
    To cause physical effects to an object.
        if (!self.manager.isDeviceMotionAvailable) {
            NSLog(@"Change your cell phone");
            return;
        }

        self.manager.deviceMotionUpdateInterval = 0.01;

        __weak typeof(self) weakSelf = self;

        [self.manager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMDeviceMotion * _Nullable motion, NSError * _Nullable error) {

            if (error != nil) {
                NSLog(@"Error %@",error);
                return;
            }
            weakSelf.gravity.gravityDirection = CGVectorMake(motion.gravity.x * 3, -motion.gravity.y * 3);
            //        self.bkView.transform = CGAffineTransformMakeRotation(atan2(motion.gravity.x, motion.gravity.y) - M_PI);
        }];

Framework usage

1. Import #import "WLBallView.h"
2. Create WLBallView control
3. Call the starMotion method to implement

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    // Pass in the name of the picture
    WLBallView * ballView = [[WLBallView alloc] initWithFrame:CGRectMake(0, 80, 50, 50) AndImageName:self.array[arc4random_uniform(4)]];
    [self.view addSubview:ballView];
    // Start exercising
    [ballView starMotion];

}

Design sketch
  • The source code can be from here. download

Keywords: iOS github Mobile simulator

Added by crash4o4 on Fri, 21 Jun 2019 22:56:54 +0300