Last updated: January 4, 2025
Dial is a workout tracking application that stores all data locally on your device using Apple's SwiftData framework.
- Your workout data is synced across your devices using your personal iCloud account
| - (void)panningEndedWithTranslation:(CGPoint)translation velocity:(CGPoint)velocity | |
| { | |
| self.panGestureRecognizer.enabled = NO; | |
| CGFloat screenHeight = [[UIScreen mainScreen] bounds].size.height; | |
| __weak ViewController *weakSelf = self; | |
| switch (self.playerState) { | |
| case PlayerStateThumbnail: | |
| if (translation.y <= -screenHeight / 3 || velocity.y <= -100) |
| - (void)panningChangedWithTranslation:(CGPoint)translation | |
| { | |
| if (self.playerViewAnimator.isRunning) | |
| { | |
| return; | |
| } | |
| CGFloat translatedY = self.view.center.y + translation.y; | |
| CGFloat progress; |
| typedef NS_ENUM(NSInteger, PlayerState) { | |
| PlayerStateThumbnail, | |
| PlayerStateFullscreen, | |
| }; | |
| @interface ViewController () | |
| @property (weak, nonatomic) IBOutlet UIView *playerView; | |
| @property (nonatomic) UIViewPropertyAnimator *playerViewAnimator; | |
| @property (nonatomic) PlayerState playerState; |
| - (void)panningBegan | |
| { | |
| if (self.playerViewAnimator.isRunning) | |
| { | |
| return; | |
| } | |
| CGRect targetFrame; | |
| switch (self.playerState) { |
| - (void)handlePan:(UIPanGestureRecognizer *)recognizer | |
| { | |
| CGPoint translation = [recognizer translationInView:self.view.superview]; | |
| if (recognizer.state == UIGestureRecognizerStateBegan) | |
| { | |
| [self panningBegan]; | |
| } | |
| if (recognizer.state == UIGestureRecognizerStateEnded) | |
| { |
| - (void)viewDidLoad | |
| { | |
| [super viewDidLoad]; | |
| self.panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; | |
| [self.view addGestureRecognizer:self.panGestureRecognizer]; | |
| } |