1
0
mirror of https://github.com/danog/Telegram.git synced 2024-12-04 02:17:51 +01:00
Telegram/Telegraph/TGNotificationWindow.m

298 lines
7.6 KiB
Mathematica
Raw Normal View History

2014-07-10 16:11:09 +02:00
#import "TGNotificationWindow.h"
#import "TGViewController.h"
#import "ActionStage.h"
#import "TGObserverProxy.h"
#import "TGAppDelegate.h"
#import <QuartzCore/QuartzCore.h>
2015-10-01 18:19:52 +02:00
@interface TGNotificationWindowView : UIView
2014-07-10 16:11:09 +02:00
{
bool _isSwipeDismissing;
}
2015-10-01 18:19:52 +02:00
@property (nonatomic, weak) UIWindow *weakWindow;
@property (nonatomic) bool isDismissed;
2014-07-10 16:11:09 +02:00
@property (nonatomic, strong) UIView *containerView;
@property (nonatomic, strong) UIView *contentView;
@end
2015-10-01 18:19:52 +02:00
@implementation TGNotificationWindowView
2014-07-10 16:11:09 +02:00
2015-10-01 18:19:52 +02:00
- (instancetype)initWithFrame:(CGRect)frame
2014-07-10 16:11:09 +02:00
{
self = [super initWithFrame:frame];
2015-10-01 18:19:52 +02:00
if (self != nil)
2014-07-10 16:11:09 +02:00
{
2015-10-01 18:19:52 +02:00
_containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 20 + 44)];
2014-07-10 16:11:09 +02:00
_containerView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
_containerView.opaque = false;
[self addSubview:_containerView];
2015-10-01 18:19:52 +02:00
_containerView.exclusiveTouch = true;
2014-07-10 16:11:09 +02:00
2015-10-01 18:19:52 +02:00
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureRecognized:)];
[_containerView addGestureRecognizer:panRecognizer];
2014-07-10 16:11:09 +02:00
}
return self;
}
- (void)setContentView:(UIView *)view
{
[_contentView removeFromSuperview];
_contentView = view;
view.frame = _containerView.bounds;
[_containerView addSubview:view];
}
- (void)animateIn
{
_isDismissed = false;
2015-10-01 18:19:52 +02:00
UIWindow *window = _weakWindow;
CGRect frame = _containerView.frame;
2014-07-10 16:11:09 +02:00
frame.origin.x = 0;
2015-10-01 18:19:52 +02:00
_containerView.frame = frame;
2014-07-10 16:11:09 +02:00
frame.origin = CGPointZero;
2015-10-01 18:19:52 +02:00
if (window.hidden || !CGRectEqualToRect(_containerView.frame, frame))
2014-07-10 16:11:09 +02:00
{
2015-10-01 18:19:52 +02:00
window.hidden = false;
2014-07-10 16:11:09 +02:00
CGRect startFrame = frame;
startFrame.origin.y = -frame.size.height;
2015-10-01 18:19:52 +02:00
_containerView.frame = startFrame;
2014-07-10 16:11:09 +02:00
[UIView animateWithDuration:0.3 animations:^
2015-10-01 18:19:52 +02:00
{
_containerView.frame = frame;
}];
2014-07-10 16:11:09 +02:00
}
}
- (void)animateOut
{
_isDismissed = true;
2015-10-01 18:19:52 +02:00
UIWindow *window = _weakWindow;
if (window.hidden)
2014-07-10 16:11:09 +02:00
return;
2015-10-01 18:19:52 +02:00
CGRect frame = _containerView.frame;
2014-07-10 16:11:09 +02:00
frame.origin.y = -frame.size.height;
[UIView animateWithDuration:0.3 animations:^
2015-10-01 18:19:52 +02:00
{
_containerView.frame = frame;
} completion:^(__unused BOOL finished)
{
window.hidden = true;
}];
2014-07-10 16:11:09 +02:00
}
- (void)panGestureRecognized:(UIPanGestureRecognizer *)recognizer
{
if (recognizer.state == UIGestureRecognizerStateChanged)
{
if (!_isDismissed)
{
CGRect frame = _containerView.frame;
frame.origin.x = [recognizer translationInView:self].x;
_containerView.frame = frame;
}
}
else if (recognizer.state == UIGestureRecognizerStateEnded || recognizer.state == UIGestureRecognizerStateCancelled)
{
2015-10-01 18:19:52 +02:00
CGFloat velocity = [recognizer velocityInView:self].x;
2014-07-10 16:11:09 +02:00
//TGLog(@"Velocity: %f", velocity);
if (ABS(velocity) < 120.0f)
{
CGRect frame = _containerView.frame;
frame.origin.x = 0;
[UIView animateWithDuration:0.3 animations:^
2015-10-01 18:19:52 +02:00
{
_containerView.frame = frame;
}];
2014-07-10 16:11:09 +02:00
}
else
{
if (ABS(velocity) < 300)
velocity = velocity < 0 ? -300 : 300;
CGRect frame = _containerView.frame;
if (velocity < 0)
frame.origin.x = -frame.size.width;
else
frame.origin.x = frame.size.width;
NSTimeInterval duration = ABS(frame.origin.x - _containerView.frame.origin.x) / ABS(velocity);
_isSwipeDismissing = true;
[UIView animateWithDuration:duration animations:^
2015-10-01 18:19:52 +02:00
{
_containerView.frame = frame;
} completion:^(BOOL finished)
{
if (finished)
{
_isSwipeDismissing = false;
UIWindow *window = _weakWindow;
window.hidden = true;
}
}];
2014-07-10 16:11:09 +02:00
}
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if (!_isSwipeDismissing)
{
CGRect frame = _containerView.frame;
frame.origin.x = 0;
[UIView animateWithDuration:0.3 animations:^
2015-10-01 18:19:52 +02:00
{
_containerView.frame = frame;
}];
2014-07-10 16:11:09 +02:00
}
[super touchesEnded:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
if (!_isSwipeDismissing)
{
CGRect frame = _containerView.frame;
frame.origin.x = 0;
[UIView animateWithDuration:0.3 animations:^
2015-10-01 18:19:52 +02:00
{
_containerView.frame = frame;
}];
2014-07-10 16:11:09 +02:00
}
[super touchesCancelled:touches withEvent:event];
}
2015-10-01 18:19:52 +02:00
@end
@interface TGNotificationWindowController : TGOverlayWindowViewController
@property (nonatomic, strong) TGNotificationWindowView *notificationView;
@property (nonatomic, weak) UIWindow *weakWindow;
@end
@implementation TGNotificationWindowController
- (void)loadView
{
[super loadView];
_notificationView = [[TGNotificationWindowView alloc] initWithFrame:self.view.bounds];
_notificationView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
_notificationView.weakWindow = _weakWindow;
[self.view addSubview:_notificationView];
}
- (TGNotificationWindowView *)notificationView
{
if (![self isViewLoaded])
[self loadView];
return _notificationView;
}
@end
@interface TGNotificationWindow ()
@end
@implementation TGNotificationWindow
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
TGNotificationWindowController *controller = [[TGNotificationWindowController alloc] init];
controller.weakWindow = self;
self.rootViewController = controller;
}
return self;
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
CGPoint localPoint = [((TGNotificationWindowController *)self.rootViewController).notificationView convertPoint:point fromView:self];
UIView *result = [((TGNotificationWindowController *)self.rootViewController).notificationView hitTest:localPoint withEvent:event];
if (result == ((TGNotificationWindowController *)self.rootViewController).notificationView || result == self.rootViewController.view)
return nil;
return result;
}
- (void)setContentView:(UIView *)view
{
[((TGNotificationWindowController *)self.rootViewController).notificationView setContentView:view];
}
- (UIView *)contentView
{
return [((TGNotificationWindowController *)self.rootViewController).notificationView contentView];
}
- (void)animateIn
{
[((TGNotificationWindowController *)self.rootViewController).notificationView animateIn];
}
- (void)animateOut
{
[((TGNotificationWindowController *)self.rootViewController).notificationView animateOut];
}
- (BOOL)_canBecomeKeyWindow
{
return false;
}
- (bool)isDismissed
{
return [((TGNotificationWindowController *)self.rootViewController).notificationView isDismissed];
}
2014-07-10 16:11:09 +02:00
- (void)performTapAction
{
2015-10-01 18:19:52 +02:00
if ([self isDismissed])
2014-07-10 16:11:09 +02:00
return;
[self animateOut];
id<ASWatcher> watcher = _watcher.delegate;
if (watcher != nil && [watcher respondsToSelector:@selector(actionStageActionRequested:options:)])
{
[watcher actionStageActionRequested:_watcherAction options:_watcherOptions];
_watcher = nil;
_watcherAction = nil;
_watcherOptions = nil;
}
}
- (void)setFrame:(CGRect)frame
{
[super setFrame:frame];
}
@end