【问题标题】:how to zoom in or out in uipageviewcontroller?如何在 uipageviewcontroller 中放大或缩小?
【发布时间】:2013-11-09 22:38:27
【问题描述】:

我有一个 uipageviewcontroller 并在 uipageviewcontroller 中设置了一个名为 contentviewcontroller 的子 viewcontroller。

thePageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation: UIPageViewControllerNavigationOrientationHorizontal options:nil];

    thePageViewController.delegate = self;
    thePageViewController.dataSource = self;

    thePageViewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

    contentViewController = [[HBDocumentChildViewController alloc] initWithPDF:PDFDocument];
    contentViewController.page = [modelArray objectAtIndex:0];
    NSArray *viewControllers = [NSArray arrayWithObject:contentViewController];
    [thePageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];

    [self addChildViewController:thePageViewController];
    [self.view addSubview:thePageViewController.view];
    thePageViewController.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
    [thePageViewController didMoveToParentViewController:self];
    self.view.gestureRecognizers = thePageViewController.gestureRecognizers;
    self.view.backgroundColor = [UIColor underPageBackgroundColor];

我已经在滚动视图类(pdfScrollView)的帮助下将pdf文件加载到uipageviewcontroller的页面中。下面是uipageviewcontroller的内容类和初始化uiscrollview类。

#import "HBDocumentChildViewController.h"

@interface HBDocumentChildViewController ()<UIWebViewDelegate>
{
    int currentPage;
    NSString*localPath;
}

@end

@implementation HBDocumentChildViewController

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Create our PDFScrollView and add it to the view controller.
    CGPDFPageRef PDFPage = CGPDFDocumentGetPage(thePDF, [_page intValue]);
    pdfScrollView = [[PDFScrollView alloc] initWithFrame:self.view.frame];
    [pdfScrollView setPDFPage:PDFPage];
    [self.view addSubview:pdfScrollView];
    self.view.backgroundColor = [UIColor whiteColor];
    self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    pdfScrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
}

下面是uiscrollview类,

/*
     File: PDFScrollView.m
 Abstract: UIScrollView subclass that handles the user input to zoom the PDF page.  This class handles swapping the TiledPDFViews when the zoom level changes.
  Version: 2


 */

#import "PDFScrollView.h"
#import "TiledPDFView.h"
#import <QuartzCore/QuartzCore.h>


@interface PDFScrollView ()

// A low resolution image of the PDF page that is displayed until the TiledPDFView renders its content.
@property (nonatomic, weak) UIImageView *backgroundImageView;

// The TiledPDFView that is currently front most.
@property (nonatomic, weak) TiledPDFView *tiledPDFView;

// The old TiledPDFView that we draw on top of when the zooming stops.
@property (nonatomic, weak) TiledPDFView *oldTiledPDFView;

@end



@implementation PDFScrollView
{
    CGPDFPageRef _PDFPage;

    // Current PDF zoom scale.
    CGFloat _PDFScale;
    CGFloat _PDFScaleH;
}


@synthesize backgroundImageView=_backgroundImageView, tiledPDFView=_tiledPDFView, oldTiledPDFView=_oldTiledPDFView;


- (id)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        self.decelerationRate = UIScrollViewDecelerationRateFast;
        self.delegate = self;
    }
    return self;
}


- (void)setPDFPage:(CGPDFPageRef)PDFPage;
{
    CGPDFPageRetain(PDFPage);
    CGPDFPageRelease(_PDFPage);
    _PDFPage = PDFPage;

    // Determine the size of the PDF page.
    CGRect pageRect = CGPDFPageGetBoxRect(_PDFPage, kCGPDFMediaBox);
    float actualHeight = pageRect.size.height;
    float actualWidth = pageRect.size.width;
    float imgRatio = actualWidth/actualHeight;
    float maxRatio = 768.0/911.0;

    if(imgRatio!=maxRatio){
        if(imgRatio < maxRatio){
            imgRatio = 911.0 / actualHeight;
            actualWidth = imgRatio * actualWidth;
            actualHeight = 911.0;
        }
        else{
            imgRatio = 768.0 / actualWidth;
            actualHeight = imgRatio * actualHeight;
            actualWidth = 768.0;
        }
    }
    pageRect.size = CGSizeMake(actualWidth, actualHeight);
    UIGraphicsBeginImageContext(pageRect.size);

    /*
     Create a low resolution image representation of the PDF page to display before the TiledPDFView renders its content.
     */
    UIGraphicsBeginImageContext(pageRect.size);

    CGContextRef context = UIGraphicsGetCurrentContext();

    // First fill the background with white.
    CGContextSetRGBFillColor(context, 1.0,1.0,1.0,1.0);
    CGContextFillRect(context,pageRect);

    CGContextSaveGState(context);
    // Flip the context so that the PDF page is rendered right side up.
    CGContextTranslateCTM(context, 0.0, pageRect.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);

    // Scale the context so that the PDF page is rendered at the correct size for the zoom level.
    CGContextScaleCTM(context, imgRatio,imgRatio);
    CGContextDrawPDFPage(context, _PDFPage);
    CGContextRestoreGState(context);

    UIImage *backgroundImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();


    if (self.backgroundImageView != nil) {
        [self.backgroundImageView removeFromSuperview];
    }

    UIImageView *backgroundImageView = [[UIImageView alloc] initWithImage:backgroundImage];
    backgroundImageView.frame = pageRect;
    backgroundImageView.contentMode = UIViewContentModeScaleAspectFit;
    [self addSubview:backgroundImageView];
    [self sendSubviewToBack:backgroundImageView];
    self.backgroundImageView = backgroundImageView;

    // Create the TiledPDFView based on the size of the PDF page and scale it to fit the view.
    TiledPDFView *tiledPDFView = [[TiledPDFView alloc] initWithFrame:pageRect scale:imgRatio];
    [tiledPDFView setPage:_PDFPage];

    [self addSubview:tiledPDFView];
    self.tiledPDFView = tiledPDFView;
}


- (void)dealloc
{
    // Clean up.
    CGPDFPageRelease(_PDFPage);
}


#pragma mark -
#pragma mark Override layoutSubviews to center content

// Use layoutSubviews to center the PDF page in the view.
- (void)layoutSubviews 
{
    [super layoutSubviews];

    // Center the image as it becomes smaller than the size of the screen.

    CGSize boundsSize = self.bounds.size;
    CGRect frameToCenter = self.tiledPDFView.frame;

    // Center horizontally.

    if (frameToCenter.size.width < boundsSize.width)
        frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
    else
        frameToCenter.origin.x = 0;

    // Center vertically.

    if (frameToCenter.size.height < boundsSize.height)
        frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
    else
        frameToCenter.origin.y = 0;

    self.tiledPDFView.frame = frameToCenter;
    self.backgroundImageView.frame = frameToCenter;

    /*
     To handle the interaction between CATiledLayer and high resolution screens, set the tiling view's contentScaleFactor to 1.0.
     If this step were omitted, the content scale factor would be 2.0 on high resolution screens, which would cause the CATiledLayer to ask for tiles of the wrong scale.
     */
    self.tiledPDFView.contentScaleFactor = 1.0;
}


#pragma mark -
#pragma mark UIScrollView delegate methods

/*
 A UIScrollView delegate callback, called when the user starts zooming.
 Return the current TiledPDFView.
 */
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return self.tiledPDFView;
}

/*
 A UIScrollView delegate callback, called when the user begins zooming.
 When the user begins zooming, remove the old TiledPDFView and set the current TiledPDFView to be the old view so we can create a new TiledPDFView when the zooming ends.
 */
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view
{
    // Remove back tiled view.
    [self.oldTiledPDFView removeFromSuperview];

    // Set the current TiledPDFView to be the old view.
    self.oldTiledPDFView = self.tiledPDFView;
    [self addSubview:self.oldTiledPDFView];
}


/*
 A UIScrollView delegate callback, called when the user stops zooming.
 When the user stops zooming, create a new TiledPDFView based on the new zoom level and draw it on top of the old TiledPDFView.
 */
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
{
    // Set the new scale factor for the TiledPDFView.
    _PDFScale *= scale;
    // Calculate the new frame for the new TiledPDFView.
    CGRect pageRect = CGPDFPageGetBoxRect(_PDFPage, kCGPDFMediaBox);
    pageRect.size = CGSizeMake(pageRect.size.width*_PDFScale, pageRect.size.height*_PDFScale);

    // Create a new TiledPDFView based on new frame and scaling.
    TiledPDFView *tiledPDFView = [[TiledPDFView alloc] initWithFrame:pageRect scale:_PDFScale];
    [tiledPDFView setPage:_PDFPage];

    // Add the new TiledPDFView to the PDFScrollView.
    [self addSubview:tiledPDFView];
    self.tiledPDFView = tiledPDFView;
}


@end

页面渲染工作正常,但我没有在页面显示视图中放大/缩小。uiscrollview 委托方法在 uipageviewcontroller 中不起作用。请帮助我找到解决此问题的方法。

【问题讨论】:

    标签: ios uiviewcontroller uiscrollview uipageviewcontroller uiscrollviewdelegate


    【解决方案1】:

    试试这个

    UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchDetected:)];
    [thePageViewController addGestureRecognizer:pinchRecognizer];
    pinchRecognizer.delegate=self;
    

    方法是

    -(void)pinchDetected:(UIPinchGestureRecognizer *)pinchRecognizer
    {
        CGFloat scale = pinchRecognizer.scale;
        thePageViewController.transform = CGAffineTransformScale(thePageViewController.transform, scale, scale);
        pinchRecognizer.scale = 1.0;
    }
    

    【讨论】:

    • @shailni:我在哪里可以在我的项目中编写此代码,请告诉我我是开发新手
    • 在 viewdidload 创建页面浏览控制器后你可以编写代码并检查它...
    • @shalini:感谢您的宝贵回复。我试过了,可以缩放页面。但是有一个问题,当它放大时没有缩放限制。我需要放大一个限制并且缩小在当前页面大小,这意味着没有从当前页面大小缩小并且还需要滚动页面,当它正在缩放并将缩小时的滚动锁定到当前页面。你能帮我找到答案吗?
    • @shalini 你能告诉我你是如何实现的吗?我在 PageViewController 的 viewDidLoad 中编写了这段代码,但出现了一些错误:“UIPageViewController 没有可见界面清除了选择器'addGestureRecognizer”。在编写 pinchDeteched 方法时还有一个错误是“在 'UIPageViewController 类型的对象上找不到属性转换”,请告诉我如何解决这个问题。
    • 你必须在类接口中包含'UIGestureRecognizerDelegate'。然后'thePageViewController.transform = CGAffineTransformScale(thePageViewController.transform, newScale, newScale);'改为,thePageViewController.view.transform = CGAffineTransformScale(thePageViewController.view.transform, newScale, newScale);。希望对你有所帮助。
    【解决方案2】:

    我已经完成了 uipageviewcontroller 的滚动和缩放。我已将上述 UIPinchGestureRecognizer 方法更改为 zoomIn 并缩小到当前页面大小。

    -(void)pinchDetected:(UIPinchGestureRecognizer *)pinchRecognizer
    
    {   
        if([pinchRecognizer state] == UIGestureRecognizerStateBegan) {
            // Reset the last scale, necessary if there are multiple objects with different scales
            lastScale = [pinchRecognizer scale];
        }
    
        if ([pinchRecognizer state] == UIGestureRecognizerStateBegan ||[pinchRecognizer state] == UIGestureRecognizerStateChanged)
        {
            CGFloat currentScale = [[[pinchRecognizer view].layer valueForKeyPath:@"transform.scale"] floatValue];
            // Constants to adjust the max/min values of zoom
            const CGFloat maxScale = 1.5;
            const CGFloat minScale = 1.0;
    
            CGFloat newScale = 1 -  (lastScale - [pinchRecognizer scale]);
            newScale = MIN(newScale, maxScale / currentScale);
            newScale = MAX(newScale, minScale / currentScale);
            thePageViewController.view.transform = CGAffineTransformScale(thePageViewController.view.transform, newScale, newScale);
            lastScale = [pinchRecognizer scale];  // Store the previous scale factor for the next pinch gesture call
        }
    }
    

    然后,我在内容视图控制器(HBDocumentChildViewController)的viewDidLoad中添加了[pdfScrollView setScrollEnabled:YES];,[pdfScrollView setContentSize:CGSizeMake(768, 1100)];代码,用于在uipageviewcontroller类中滚动内容视图。

     - (void)viewDidLoad
        {
            [super viewDidLoad];
    
            // Create our PDFScrollView and add it to the view controller.
            CGPDFPageRef PDFPage = CGPDFDocumentGetPage(thePDF, [_page intValue]);
            pdfScrollView = [[PDFScrollView alloc] initWithFrame:self.view.frame];
             pdfScrollView.bouncesZoom = YES;
            [pdfScrollView setScrollEnabled:YES];
            [pdfScrollView setContentSize:CGSizeMake(768, 1100)];
            [pdfScrollView setPDFPage:PDFPage];
            [self.view addSubview:pdfScrollView];
            self.view.backgroundColor = [UIColor whiteColor];
            self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
            pdfScrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
            pdfScrollView.delegate = pdfScrollView;
    
        }
    

    尝试使用此代码放大和缩小到当前页面大小并滚动 uipageviewcontroller 的内容。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-24
    • 1970-01-01
    • 2018-04-06
    相关资源
    最近更新 更多