1
0
mirror of https://github.com/danog/Telegram.git synced 2024-12-02 09:27:55 +01:00
Telegram/Telegraph/TGEditingScrollView.m
2014-07-10 18:11:09 +04:00

241 lines
6.8 KiB
Objective-C

/*
* This is the source code of Telegram for iOS v. 1.1
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Peter Iakovlev, 2013.
*/
#import "TGEditingScrollView.h"
#import "TGCollectionItem.h"
#import "TGEditableCollectionItemView.h"
#import "TGEditingScrollViewGestureRecognizer.h"
@interface UIScrollView () <UIGestureRecognizerDelegate>
@end
@interface TGEditingScrollView () <UIScrollViewDelegate>
{
bool _processedCurrentScroll;
bool _restoreBounds;
TGEditingScrollViewGestureRecognizer *_editingRecognizer;
}
@end
@implementation TGEditingScrollView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self != nil)
{
self.scrollsToTop = false;
self.showsHorizontalScrollIndicator = false;
self.showsVerticalScrollIndicator = false;
self.alwaysBounceHorizontal = true;
self.decelerationRate = UIScrollViewDecelerationRateFast;
//_editingRecognizer = [[TGEditingScrollViewGestureRecognizer alloc] init];
//[self addGestureRecognizer:_editingRecognizer];
//[self.panGestureRecognizer requireGestureRecognizerToFail:_editingRecognizer];
self.delegate = self;
}
return self;
}
- (CGFloat)optionsWidth
{
return self.contentSize.width - self.bounds.size.width;
}
- (void)scrollViewWillEndDragging:(UIScrollView *)__unused scrollView withVelocity:(CGPoint)__unused velocity targetContentOffset:(inout CGPoint *)targetContentOffset
{
CGFloat optionsWidth = [self optionsWidth];
if (targetContentOffset != NULL)
{
if (targetContentOffset->x > optionsWidth / 2.0f)
{
targetContentOffset->x = optionsWidth;
[self _setOptionsAreRevealedAndNotify:true];
}
else
{
targetContentOffset->x = 0.0f;
[self _setOptionsAreRevealedAndNotify:false];
}
}
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)__unused scrollView
{
if (ABS(self.contentOffset.x) < FLT_EPSILON)
_processedCurrentScroll = false;
}
- (void)scrollViewDidScroll:(UIScrollView *)__unused scrollView
{
if (self.bounds.origin.x > FLT_EPSILON)
{
if (!_processedCurrentScroll)
{
_processedCurrentScroll = true;
id<TGEditingScrollViewDelegate> editingDelegate = _editingDelegate;
if ([editingDelegate respondsToSelector:@selector(editingScrollViewWillRevealOptions:)])
[editingDelegate editingScrollViewWillRevealOptions:self];
}
}
}
- (void)_setOptionsAreRevealedAndNotify:(bool)optionsAreRevealed
{
if (_optionsAreRevealed != optionsAreRevealed)
_optionsAreRevealed = optionsAreRevealed;
if (!_optionsAreRevealed && _processedCurrentScroll)
{
id<TGEditingScrollViewDelegate> editingDelegate = _editingDelegate;
if ([editingDelegate respondsToSelector:@selector(editingScrollViewDidHideOptions:)])
[editingDelegate editingScrollViewDidHideOptions:self];
}
}
- (void)setOptionsAreRevealed:(bool)optionsAreRevealed
{
[self setOptionsAreRevealed:optionsAreRevealed animated:false];
}
- (void)setOptionsAreRevealed:(bool)optionsAreRevealed animated:(bool)animated
{
if (_optionsAreRevealed != optionsAreRevealed)
{
_optionsAreRevealed = optionsAreRevealed;
if (_optionsAreRevealed && _processedCurrentScroll)
{
_processedCurrentScroll = true;
id<TGEditingScrollViewDelegate> editingDelegate = _editingDelegate;
if ([editingDelegate respondsToSelector:@selector(editingScrollViewWillRevealOptions:)])
[editingDelegate editingScrollViewWillRevealOptions:self];
}
CGPoint targetContentOffset = CGPointMake(_optionsAreRevealed ? [self optionsWidth] : 0.0f, 0.0f);
if (animated)
{
[self _postOffsetChangeNotification];
[UIView animateWithDuration:0.3 delay:0.0 options:(iosMajorVersion() >= 7 ? (7 << 16) : 0) animations:^
{
[self setContentOffset:targetContentOffset animated:false];
} completion:nil];
}
else
[self setContentOffset:targetContentOffset animated:false];
}
}
- (void)setContentSize:(CGSize)contentSize
{
_restoreBounds = true;
[super setContentSize:contentSize];
_restoreBounds = false;
}
- (void)setFrame:(CGRect)frame
{
_restoreBounds = true;
[super setFrame:frame];
_restoreBounds = false;
}
- (void)setContentOffset:(CGPoint)contentOffset
{
contentOffset.x = MAX(0.0f, contentOffset.x);
[super setContentOffset:contentOffset];
[self _postOffsetChangeNotification];
}
- (void)setBounds:(CGRect)bounds
{
CGRect previousBounds = self.bounds;
if (_restoreBounds)
bounds.origin.x = previousBounds.origin.x;
bounds.origin.x = MAX(0.0f, bounds.origin.x);
[super setBounds:bounds];
}
- (void)layoutSubviews
{
[super layoutSubviews];
}
- (void)_postOffsetChangeNotification
{
id<TGEditingScrollViewDelegate> editingDelegate = _editingDelegate;
[editingDelegate editingScrollViewOptionsOffsetChanged:self];
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer == self.panGestureRecognizer)
return self.bounds.origin.x > FLT_EPSILON || (!_lockScroll && !_disableScroll);
return [super gestureRecognizerShouldBegin:gestureRecognizer];
}
#pragma mark -
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if (!_lockScroll && self.bounds.origin.x < FLT_EPSILON)
{
if (((TGCollectionItem *)((TGCollectionItemView *)self.superview).boundItem).selectable)
[(TGCollectionItemView *)self.superview setHighlighted:true];
}
[super touchesBegan:touches withEvent:event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if (((UICollectionViewCell *)self.superview).highlighted)
{
[(UICollectionViewCell *)self.superview setHighlighted:false];
[(TGEditableCollectionItemView *)self.superview _requestSelection];
}
else
[(TGEditableCollectionItemView *)self.superview setShowsEditingOptions:false animated:true];
[super touchesEnded:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
if (((UICollectionViewCell *)self.superview).highlighted)
[(UICollectionViewCell *)self.superview setHighlighted:false];
[super touchesMoved:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[(UICollectionViewCell *)self.superview setHighlighted:false];
[super touchesCancelled:touches withEvent:event];
}
@end