【问题标题】:Image dragging on a UIScrollView在 UIScrollView 上拖动图像
【发布时间】:2023-04-05 13:50:02
【问题描述】:

当用户触摸UITableViewCell 上的图像时,会调用UIViewController。 它使用modalViewController 调用。 在这个modalViewController 上是一个UIScrollView,中间有另一个UIImageView,它使用NSDictionary(从UITableViewCell 传递)获取图像。

现在,我想要实现的是用户只能垂直拖动图像的能力,这样稍微拖动和释放就会导致图像以动画方式返回到中心。如果用户将其拖到极端,则整个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];
}

此处的所有代码都是对MWPhotoBrowserUITapView 的自定义副本的修改。

【问题讨论】:

  • 为什么要使用 imageMoved BOOL 值?如果图像在屏幕中心并且您不移动它,它的 pos.y 将始终 >50 &&
  • 除非我使用此 BOOL 变量,否则即使用户不拖动图像,模态也会关闭,并在极端情况下单击(顶部和底部 50 像素)。因此,这是必要的。
  • 我的解决方案有帮助吗?
  • 对不起。我还没有时间集成这个模块。我一到这个就会通知你。 :)

标签: iphone ios objective-c uiscrollview mwphotobrowser


【解决方案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];
    }
}
}

【讨论】:

  • BCViewController.h 是我必须从某个地方获取的外部标头,我想??
  • 是的,如果你愿意,我可以包含标题。
  • 在示例中添加了标题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-01
  • 1970-01-01
相关资源
最近更新 更多