ios - 在 UIScrollView 中缩放 UIImageView 行为很奇怪

标签 ios imageview zooming scrollview

伙计们,我有以下问题。我有一个非常像 Apple 的 PhotoScroller 的应用程序。我想通过滑动屏幕从一个图像跳到另一个图像。我可以做到这一点,但我无法缩放图像。这就是问题所在 - 我有一个包含图像的数组。如果数组里面只有一个对象,那么缩放是没有问题的。但是如果阵列中有更多图像,当我尝试缩放时它们会表现得很奇怪。图像没有被缩放,它会离开屏幕到它想要的地方。这是我的代码:

int pageWidth = 1024;
int pageHeight = 768;
int counter = 0;

self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, pageWidth, pageHeight)];

CGRect containerFrame = self.view.frame;
scrollView = [[UIScrollView alloc] initWithFrame:containerFrame];
[self.view addSubview:scrollView];

NSMutableArray *all = [[NSMutableArray alloc] init];
[all addObject:[UIImage imageNamed:@"222.jpg"]];

CGSize scrollSize = CGSizeMake(pageWidth * [all count], pageHeight);
[scrollView setContentSize:scrollSize];



for (UIImage *image in all)
{
    UIImage *pageImage = [[UIImage alloc] init];
    pageImage = [all objectAtIndex:counter];

    CGRect scrollFrame = CGRectMake(pageWidth * counter, 0, pageWidth, pageHeight);
    miniScrollView = [[UIScrollView alloc] initWithFrame:scrollFrame];
    [scrollView addSubview:miniScrollView];

    CGSize miniScrollSize = CGSizeMake(pageImage.size.width, pageImage.size.height);
    [miniScrollView setContentSize:miniScrollSize];

    UIImageView *tempImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, pageImage.size.width, pageImage.size.height)];
    tempImageView.image = [all objectAtIndex:counter];
    self.imageView = tempImageView;

    miniScrollView.maximumZoomScale = 3.0;
    miniScrollView.minimumZoomScale = 1.0;
    miniScrollView.clipsToBounds = YES;
    miniScrollView.delegate = self;
    miniScrollView.showsHorizontalScrollIndicator = NO;
    miniScrollView.showsVerticalScrollIndicator = NO;
    miniScrollView.bouncesZoom = YES;
    [miniScrollView addSubview:imageView];

    counter ++;
}
[scrollView setPagingEnabled:YES];
[scrollView setScrollEnabled:YES];
}


-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return imageView;
}

你知道哪里出了问题吗?因为我试图用将近 2 周的时间完成这项工作。

最佳答案

我也曾开发过此类应用程序。您可以做的第一件事是采用 ScrollView 的单独子类,以便可以轻松处理所有分页和缩放操作。在您的 scrollView 类中,您可以引用以下代码片段。

@interface PhotoScrollView : UIScrollView<UIScrollViewDelegate,UIGestureRecognizerDelegate>
{
int finalPhotoWidth;
int finalPhotoHeight;
}


 // to contain image
 @property (strong, nonatomic) UIImageView *imageView;

 - (id)initWithFrame:(CGRect)frame andImage:(UIImage *)photo
 {
   self = [super initWithFrame:frame];
    if (self) 
    {
    // Initialization code

    [self initializeScrollViewWithImage:photo];

    //setting gesture recognizer for single tap
     UITapGestureRecognizer  *singleTapRecognizer    =   [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(scrollViewSingleTapped:)];
     singleTapRecognizer.delegate    =   self;
     singleTapRecognizer.numberOfTapsRequired    =   1;
     [self addGestureRecognizer:singleTapRecognizer];


     //setting gesture recognizer for Double tap
     UITapGestureRecognizer *doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(scrollViewDoubleTapped:)];
     doubleTapRecognizer.delegate    =   self;
     doubleTapRecognizer.numberOfTapsRequired = 2;

    [self addGestureRecognizer:doubleTapRecognizer];
    [singleTapRecognizer requireGestureRecognizerToFail:doubleTapRecognizer];

    singleTapActivated  =   FALSE;

    self.backgroundColor    =   [UIColor blackColor];

    self.minimumZoomScale = 1.0f;
    self.maximumZoomScale = 15.0f;
    self.zoomScale = 1.0f;

    self.delegate   =   self;
}
return self;
}


//for sizing the frame by giving height and width
-(void)initializeScrollViewWithImage:(UIImage*)photo
{

finalPhotoWidth = photo.size.width;
finalPhotoHeight = photo.size.height;

//Pre-checking of frame and setting the height and width accordingly

 if (finalPhotoHeight > self.frame.size.height)
 {
    // if photo height is bigger than frame height, re-adjust the photo height and width accordingly

    finalPhotoHeight = self.frame.size.height;
    finalPhotoWidth = (photo.size.width/photo.size.height) * finalPhotoHeight;
}
 if (finalPhotoWidth > self.frame.size.width)
 {
    // if photo width is bigger than frame width, re-adjust the photo height and width accordingly

    finalPhotoWidth = self.frame.size.width;
    finalPhotoHeight = (photo.size.height/photo.size.width) * finalPhotoWidth;
 }
  if (finalPhotoHeight < self.frame.size.height && finalPhotoWidth < self.frame.size.width)
  {
    // if the photo is smaller than frame, increase the photo width and height accordingly

    finalPhotoWidth = self.frame.size.width;
    finalPhotoHeight    =   self.frame.size.height;
  }

  //initialising imageView with the thumbnail photo

  self.imageView = [[UIImageView alloc] initWithImage:photo];
  self.imageView.contentMode = UIViewContentModeScaleAspectFit;

  //setting frame according to the modified width and height
  if(!isnan(finalPhotoWidth) && !isnan(finalPhotoHeight))
  {
    self.imageView.frame = CGRectMake( (self.frame.size.width - finalPhotoWidth) / 2,    (self.frame.size.height - finalPhotoHeight)/2, finalPhotoWidth,  finalPhotoHeight);

  }

  // setting scrollView properties

  self.contentSize    =   self.imageView.frame.size;

  // add image view to scroll view
  [self addSubview:self.imageView]; 
}

 //to deny the simultaneous working of single and double taps
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{

return NO;
}

// Gesture handleer for single tap gesture
-(void)scrollViewSingleTapped:(UITapGestureRecognizer *)recognizer
{
 if(!singleTapActivated)
 {
 //do as per requirement
       singleTapActivated  =   TRUE;
 }

else
{
    //do as per requirement
    singleTapActivated  =   FALSE;
}
}


//for zooming after double tapping
- (void)scrollViewDoubleTapped:(UITapGestureRecognizer*)recognizer
{

//to check whether image is zoomed
if (self.zoomScale != 1.0f)
{
    //if image is zoomed, then zoom out


    [self setZoomScale:1.0 animated:YES];
    self.imageView.frame = CGRectMake( (self.frame.size.width - finalPhotoWidth) / 2, (self.frame.size.height - finalPhotoHeight)/2, finalPhotoWidth,  finalPhotoHeight);

    [self.observer photoZoomStopped];

}
else
{

    // get the point of image which is double tapped
    CGPoint pointInView = [recognizer locationInView:self.imageView];

    // Get a zoom scale that's zoomed in slightly, capped at the maximum zoom scale specified by the scroll view
    CGFloat newZoomScale = self.zoomScale * 4.0f;
    newZoomScale = MIN(newZoomScale, self.maximumZoomScale);

    // Figure out the rect we want to zoom to, then zoom to it

    CGSize scrollViewSize = self.imageView.frame.size;


    CGFloat w = scrollViewSize.width / newZoomScale;
    CGFloat h = scrollViewSize.height / newZoomScale;
    CGFloat x = pointInView.x - (w / 2.0f);
    CGFloat y = pointInView.y - (h / 2.0f);

    CGRect rectToZoomTo = CGRectMake(x, y, w, h);

    [self zoomToRect:rectToZoomTo animated:YES];
}

}

// To re-center the image after zooming in and zooming out
- (void)centerScrollViewContents
{
CGSize boundsSize = self.bounds.size;
CGRect contentsFrame = self.imageView.frame;

if (contentsFrame.size.width < boundsSize.width)
{
    contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2.0f;
}
else
{
    contentsFrame.origin.x = 0.0f;
}

if (contentsFrame.size.height < boundsSize.height)
{
    contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2.0f;
}
else
{
    contentsFrame.origin.y = 0.0f;
}

self.imageView.frame = contentsFrame;
}

//for zooming in and zooming out
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
if (self.zoomScale > 1.0f)
{
    [self.observer photoZoomStarted];

    [self centerScrollViewContents];
}
else
{
    self.bouncesZoom    =   NO;

    [self.observer photoZoomStopped];

        // for zooming out by pinching
    [self centerScrollViewContents];
}

// The scroll view has zoomed, so we need to re-center the contents
}

- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}

如果有帮助,请告诉我。谢谢:)

关于ios - 在 UIScrollView 中缩放 UIImageView 行为很奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21755255/

相关文章:

objective-c - 使用 UIPinchGestureRecognizer 缩放整个屏幕

c - goocanvas - 坐标系和缩放到光标

ios - 错误 :Passing address of non-scalar object to __autoreleasing parameter for write-back

ios - 类似键盘的弹出按钮,iOS

android - 在 Android Imageview 上禁用抗锯齿

java - 带有来自特殊 HashMap 的图像的 Android ListView

javascript - 如何在 ChartJS 中设置时间刻度缩放?

ios - Xamarin Forms 应用程序 - 错误 ITMS-90171 bundle 结构无效

ios - JTAppleCalendar - 如何停止单元格随机重复?

android - 如何使用 Drawable 图像名称从 ArrayList<String> 动态设置 ImageViews 源?