2013-05-01 84 views
1

當用戶觸摸UITableViewCell上的圖像時,會調用UIViewController。 它使用modalViewController來調用。 在此modalViewControllerUIScrollView,中間有另一個UIImageView,它使用NSDictionary(從UITableViewCell傳遞)獲取圖像。在UIScrollView上拖動圖像

現在,我想要實現的是用戶只能垂直拖動圖像的能力,這樣拖動和釋放一點會使圖像返回到動畫中心。如果用戶將其拖到極端,則整個UIScrollView將被解僱,並且用戶返回到UITableView。我使用了下面的代碼。這裏的問題是,正如我的名字所暗示的,這個代碼很粗糙。有沒有這樣做的優雅方式,而不需要這麼多的計算?

BOOL imageMoved=NO; 

- (void) touchesMoved:(NSSet *)touches 
     withEvent:(UIEvent *)event { 
UITouch * touch = [touches anyObject]; 
CGPoint pos = [touch locationInView: [UIApplication sharedApplication].keyWindow]; 

CGRect imageRect = _photoImageView.frame;//_photoImageView object of UIImageView 
CGFloat imageHeight = imageRect.size.height;//getting height of the image 
CGFloat imageTop=240-imageHeight/2; 
CGFloat imageBottom=imageTop+imageHeight;//setting boundaries for getting coordinates of touch. 
// Touches that originate above imageTop and below imageBottom are ignored(until touch reaches UIImageView) 

if (pos.y>50&&pos.y<430&&pos.y>=imageTop&&pos.y<=imageBottom){//extremes are defined as top and bottom 50 pixels. 
    imagedMoved=YES;//BOOL variable to hold if the image was dragged or not 
    NSLog(@"%f", pos.y); 
    [UIView setAnimationDelay:0]; 

    [UIView animateWithDuration:0.4 

        animations:^{_photoImageView.frame=CGRectMake(0,pos.y-imageHeight/2,320,200);} 

        completion:^(BOOL finished){ }]; 
} 
} 

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 

UITouch * touch = [touches anyObject]; 
CGPoint pos = [touch locationInView: [UIApplication sharedApplication].keyWindow]; 

if (pos.y>50&&pos.y<430){//if touch has NOT ended in the extreme 50 pixels vertically 
    [UIView setAnimationDelay:0];//restoring UIImageView to original center with animation 

    [UIView animateWithDuration:0.4 

        animations:^{_photoImageView.frame=CGRectMake(0,140,320,200);} 

        completion:^(BOOL finished){ }]; 
imagedMoved=NO;//prepare BOOL value for next touch event 
} 

else if(pos.y<50||pos.y>430) 
    if(imagedMoved) 
    [self.photoBrowser exit] ;//exit function(imported from UIScrollViewController) dismisses 
        //modalView using [self dismissViewControllerAnimated:YES completion:nil]; 
} 

這裏的所有代碼是修改到的UITapViewMWPhotoBrowser定製的副本。

+0

你爲什麼要使用imageMoved BOOL值?如果圖像居中在屏幕上,並且不移動它,它的pos.y總是> 50 && <430,所以if(imageMoved)檢查是無用的。你有沒有想過使用UIPanGestureRecognizer而不是原始的觸摸事件? – 2013-05-01 19:34:37

+0

除非我使用BOOL變量,否則即使用戶不拖動圖像,模式也會關閉,並在極端(頂部和底部50像素)點擊。因此它是必要的。 – n00bProgrammer 2013-05-04 05:50:53

+0

我的解決方案有幫助嗎? – 2013-05-10 19:21:01

回答

1

喲,這是一個更簡單的方法來做到這一點,或多或少的例子,亞歷山德羅說。我沒有找到屏幕的頂部,但我給它的幻覺。

BCViewController.h

#import <UIKit/UIKit.h> 

@interface BCViewController : UIViewController <UIScrollViewDelegate> 
@property (weak, nonatomic) IBOutlet UIScrollView *svScroller; 
@property (weak, nonatomic) IBOutlet UIImageView *ivFish; 

@end 




#import "BCViewController.h" 

@interface BCViewController(){ 
    UIPanGestureRecognizer *_panGestureRecognizer; 
    CGPoint     _fishOrigin; 
} 

@end 

@implementation BCViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.svScroller.delegate = self; 
    [self.svScroller setContentSize:self.view.frame.size]; 
    self.svScroller.translatesAutoresizingMaskIntoConstraints = NO; 
    self.ivFish.userInteractionEnabled = YES; 

    _panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanFrom:)]; 
    [self.ivFish addGestureRecognizer:_panGestureRecognizer]; 

    _fishOrigin = self.ivFish.center; 

    NSLog(@"center %f", self.ivFish.center.x); 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

-(void)handlePanFrom:(UIPanGestureRecognizer *)recognizer{ 
    // if you want it but not used 
    CGPoint translation = [recognizer translationInView:recognizer.view]; 
    // if you want it but not used 
    CGPoint velocity = [recognizer velocityInView:recognizer.view]; 
    CGPoint tempPoint; 


if (recognizer.state == UIGestureRecognizerStateBegan) { 

} else if (recognizer.state == UIGestureRecognizerStateChanged) { 
    tempPoint = [recognizer locationInView:self.view]; 

    self.ivFish.center = CGPointMake(175.5, tempPoint.y); 

} else if (recognizer.state == UIGestureRecognizerStateEnded) { 
    CGPoint tempPoint; 
    tempPoint = [recognizer locationInView:self.view]; 

    if (tempPoint.y < 132) { 
     [UIView animateWithDuration:.3 delay:0 
          options:UIViewAnimationOptionCurveEaseOut 
         animations:^ { 
          [self.navigationController popViewControllerAnimated:TRUE]; 
         } 
         completion:NULL]; 
    } else { 
     [UIView animateWithDuration:.3 delay:0 
          options:UIViewAnimationOptionCurveEaseOut 
         animations:^ { 
          self.ivFish.center = _fishOrigin; 
         } 
         completion:NULL]; 
    } 
} 
} 
+0

BCViewController.h是我必須從某處獲得的外部頭,我想? – n00bProgrammer 2013-05-08 12:52:08

+0

是的我可以包括標題,如果你喜歡。 – 2013-05-08 13:40:37

+1

爲示例添加了標題 – 2013-05-08 13:43:05