Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // PoliteScrollView.h
- #import <UIKit/UIKit.h>
- @interface PoliteScrollView : UIScrollView
- // number of pixels perpendicular to the scroll views orientation to make a drag start counting as a subview drag
- // defaults to 1/10 of the scroll view's width or height, whichever is smaller
- @property(nonatomic,assign) CGFloat subviewDraggingThreshold;
- // yes when a subview is being dragged
- @property(nonatomic,assign) BOOL isDraggingSubview;
- // the subview being dragged
- @property(nonatomic,strong) UIView *draggingSubview;
- @end
- @protocol PoliteScrollViewDelegate <NSObject>
- @optional
- - (void)scrollView:(PoliteScrollView *)scrollView subviewTouchesBegan:(NSSet *)touches;
- - (void)scrollView:(PoliteScrollView *)scrollView subviewTouchesMoved:(NSSet *)touches;
- - (void)scrollView:(PoliteScrollView *)scrollView subviewTouchesEnded:(NSSet *)touches;
- @end
- // PoliteScrollView.m
- #import "PoliteScrollView.h"
- @interface PoliteScrollView ()
- @property(nonatomic,assign) CGPoint startLocation;
- @property(nonatomic,strong) UIView *hitView;
- @end
- @implementation PoliteScrollView
- @synthesize startLocation=_startLocation;
- @synthesize hitView=_hitView;
- @synthesize subviewDraggingThreshold=_subviewDraggingThreshold;
- @synthesize isDraggingSubview=_isDraggingSubview;
- @synthesize draggingSubview=_draggingSubview;
- - (BOOL)isHorizontal {
- return self.frame.size.width > self.frame.size.height;
- }
- - (CGFloat)subviewDraggingThreshold {
- if (_subviewDraggingThreshold == 0.0) {
- CGFloat orthoSize = ([self isHorizontal])? self.frame.size.height : self.frame.size.width;
- _subviewDraggingThreshold = orthoSize / 10.0;
- }
- return _subviewDraggingThreshold;
- }
- - (BOOL)isOrthoganalDrag:(CGPoint)delta {
- if ([self isHorizontal]) {
- return fabsf(delta.y) > self.subviewDraggingThreshold;
- } else {
- return fabsf(delta.x) > self.subviewDraggingThreshold;
- }
- }
- - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
- [super touchesBegan:touches withEvent:event];
- CGPoint location = [[touches anyObject] locationInView:self];
- for (UIView *view in self.subviews) {
- if (CGRectContainsPoint(view.frame, location)) {
- self.hitView = view;
- self.startLocation = location;
- break;
- }
- }
- }
- - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
- [super touchesMoved:touches withEvent:event];
- if (self.isDraggingSubview) {
- if (self.delegate && [self.delegate respondsToSelector:@selector(scrollView:subviewTouchesMoved:)]) {
- [(id <PoliteScrollViewDelegate>)self.delegate scrollView:self subviewTouchesMoved:touches];
- }
- [self.draggingSubview touchesMoved:touches withEvent:event];
- } else {
- CGPoint location = [[touches anyObject] locationInView:self];
- CGPoint delta = CGPointMake(location.x-self.startLocation.x, location.y-self.startLocation.y);
- if ([self isOrthoganalDrag:delta]) {
- self.draggingSubview = self.hitView;
- self.isDraggingSubview = YES;
- self.scrollEnabled = NO;
- if (self.delegate && [self.delegate respondsToSelector:@selector(scrollView:subviewTouchesBegan:)]) {
- [(id <PoliteScrollViewDelegate>)self.delegate scrollView:self subviewTouchesBegan:touches];
- }
- [self.draggingSubview touchesBegan:touches withEvent:event];
- }
- }
- }
- - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
- [super touchesEnded:touches withEvent:event];
- if (self.isDraggingSubview) {
- if (self.delegate && [self.delegate respondsToSelector:@selector(scrollView:subviewTouchesEnded:)]) {
- [(id <PoliteScrollViewDelegate>)self.delegate scrollView:self subviewTouchesEnded:touches];
- }
- [self.draggingSubview touchesEnded:touches withEvent:event];
- self.isDraggingSubview = NO;
- self.scrollEnabled = YES;
- self.draggingSubview = nil;
- }
- }
- @end
- // DraggableImageView.h
- #import <Foundation/Foundation.h>
- @interface DraggableImageView : UIImageView
- - (id)initWithImageView:(UIImageView *)imageView;
- @end
- // DraggableImageView.m
- #import "DraggableImageView.h"
- @interface DraggableImageView ()
- @property(assign,nonatomic) CGPoint startLocation;
- @end
- @implementation DraggableImageView
- @synthesize startLocation=_startLocation;
- - (id)initWithImageView:(UIImageView *)imageView {
- self = [super initWithImage:imageView.image];
- if (self) {
- }
- return self;
- }
- - (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
- CGPoint location = [[touches anyObject] locationInView:self];
- self.startLocation = location;
- }
- - (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
- CGPoint location = [[touches anyObject] locationInView:self];
- CGPoint prevlocation = [[touches anyObject] previousLocationInView:self];
- self.frame = CGRectOffset(self.frame, location.x-prevlocation.x, location.y-prevlocation.y);
- }
- @end
- // ViewController.m
- #import "ViewController.h"
- #import "PoliteScrollView.h"
- #import "DraggableImageView.h"
- #define kPUPPY_COUNT 5
- #define kPUPPY_WIDTH 100
- #define kPUPPY_HEIGHT 100
- @interface ViewController ()
- @property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
- @property (strong,nonatomic) DraggableImageView *dragImage;
- @end
- @implementation ViewController
- @synthesize scrollView=_scrollView;
- @synthesize dragImage=_dragImage;
- - (void)initScrollView {
- for(UIView *subview in [self.scrollView subviews]) [subview removeFromSuperview];
- for (int i=0; i<kPUPPY_COUNT; i++) {
- UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"puppy%d.jpeg", i]];
- UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
- imageView.frame = CGRectMake(i*kPUPPY_WIDTH, 0.0, kPUPPY_WIDTH, kPUPPY_HEIGHT);
- [self.scrollView addSubview:imageView];
- }
- self.scrollView.clipsToBounds = NO;
- self.scrollView.contentSize = CGSizeMake(kPUPPY_COUNT*kPUPPY_WIDTH, kPUPPY_HEIGHT);
- }
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- [self initScrollView];
- }
- - (void)viewDidUnload
- {
- [self setScrollView:nil];
- [super viewDidUnload];
- // Release any retained subviews of the main view.
- }
- - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
- {
- return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
- }
- - (IBAction)startOver:(id)sender {
- for (UIView *view in [self.view subviews]) {
- if ([view isKindOfClass:[DraggableImageView self]]) {
- [view removeFromSuperview];
- }
- }
- }
- - (void)scrollView:(PoliteScrollView *)scrollView subviewTouchesBegan:(NSSet *)touches {
- self.dragImage = [[DraggableImageView alloc] initWithImageView:(UIImageView *)scrollView.draggingSubview];
- self.dragImage.frame = [scrollView convertRect:scrollView.draggingSubview.frame toView:self.view];
- [self.view addSubview:self.dragImage];
- [self.dragImage touchesBegan:touches withEvent:nil];
- }
- - (void)scrollView:(PoliteScrollView *)scrollView subviewTouchesMoved:(NSSet *)touches {
- [self.dragImage touchesMoved:touches withEvent:nil];
- }
- - (void)scrollView:(PoliteScrollView *)scrollView subviewTouchesEnded:(NSSet *)touches {
- [self.dragImage touchesEnded:touches withEvent:nil];
- }
- @end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement