在旋转iPhone / iPad上将图像适合屏幕?

时间:2010-06-02 22:29:45

标签: iphone

我一直在玩Apple的网站(ScrollViewSuite)上的一个iPhone示例。我试图稍微调整它,以便当我旋转iPad时,图像将以横向模式垂直放入屏幕。我成功地使图像旋转,但图像大于横向屏幕的高度,因此底部位于屏幕下方。我想将图像缩放到景观屏幕的高度。

我一直在玩各种autoSizingMask属性而没有成功。

imageView被称为“zoomView”,这是加载到名为imageScrollView的scrollView中的实际图像。

我正在尝试实现旋转的屏幕,看起来像这样....对不起只有1个链接允许新用户:(

olsonvox.com/photos/correct.png

然而,这就是我的屏幕看起来像。

http://www.olsonvox.com/photos/incorrect.png

我真的很感激一些建议或指导。下面是项目的RootViewController.m。

  • 刀片

    import "RootViewController.h"
    
        #define ZOOM_VIEW_TAG 100
        #define ZOOM_STEP 1.5
    
        #define THUMB_HEIGHT 150
        #define THUMB_V_PADDING 25
        #define THUMB_H_PADDING 25
        #define CREDIT_LABEL_HEIGHT 25
    
        #define AUTOSCROLL_THRESHOLD 30
    
        @interface RootViewController (ViewHandlingMethods)
        - (void)toggleThumbView;
        - (void)pickImageNamed:(NSString *)name;
        - (NSArray *)imageNames;
        - (void)createThumbScrollViewIfNecessary;
        - (void)createSlideUpViewIfNecessary;
        @end
    
        @interface RootViewController (AutoscrollingMethods)
        - (void)maybeAutoscrollForThumb:(ThumbImageView *)thumb;
        - (void)autoscrollTimerFired:(NSTimer *)timer;
        - (void)legalizeAutoscrollDistance;
        - (float)autoscrollDistanceForProximityToEdge:(float)proximity;
        @end
    
        @interface RootViewController (UtilityMethods)
        - (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center;
        @end
    
    
        @implementation RootViewController
    
        - (void)loadView {
            [super loadView];
    
            imageScrollView = [[UIScrollView alloc] initWithFrame:[[self view]bounds]];
    
         // this code makes the image resize to the width and height properly. 
         imageScrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin|  UIViewAutoresizingFlexibleBottomMargin| UIViewAutoresizingFlexibleBottomMargin;
    
         // TRY SETTNG CENTER HERE SOMEHOW>....
    
    
         [imageScrollView setBackgroundColor:[UIColor blackColor]];
            [imageScrollView setDelegate:self];
            [imageScrollView setBouncesZoom:YES];
            [[self view] addSubview:imageScrollView];
         [self toggleThumbView];
    
    
         // intitializes with the first image.
    
            [self pickImageNamed:@"lookbook1"];
        }
    
        - (void)dealloc {
            [imageScrollView release];
            [slideUpView release];
            [thumbScrollView release];
            [super dealloc];
        }
    
        #pragma mark UIScrollViewDelegate methods
    
        - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
            UIView *view = nil;
            if (scrollView == imageScrollView) {
                view = [imageScrollView viewWithTag:ZOOM_VIEW_TAG];
            }
            return view;
        }
    
        /************************************** NOTE **************************************/
        /* The following delegate method works around a known bug in zoomToRect:animated: */
        /* In the next release after 3.0 this workaround will no longer be necessary      */
        /**********************************************************************************/
        - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale {
            [scrollView setZoomScale:scale+0.01 animated:NO];
            [scrollView setZoomScale:scale animated:NO];
        }
    
        #pragma mark TapDetectingImageViewDelegate methods
    
        - (void)tapDetectingImageView:(TapDetectingImageView *)view gotSingleTapAtPoint:(CGPoint)tapPoint {
            // Single tap shows or hides drawer of thumbnails.
            [self toggleThumbView];
        }
    
        - (void)tapDetectingImageView:(TapDetectingImageView *)view gotDoubleTapAtPoint:(CGPoint)tapPoint {
            // double tap zooms in
            float newScale = [imageScrollView zoomScale] * ZOOM_STEP;
            CGRect zoomRect = [self zoomRectForScale:newScale withCenter:tapPoint];
            [imageScrollView zoomToRect:zoomRect animated:YES];
        }
    
        - (void)tapDetectingImageView:(TapDetectingImageView *)view gotTwoFingerTapAtPoint:(CGPoint)tapPoint {
            // two-finger tap zooms out
            float newScale = [imageScrollView zoomScale] / ZOOM_STEP;
            CGRect zoomRect = [self zoomRectForScale:newScale withCenter:tapPoint];
            [imageScrollView zoomToRect:zoomRect animated:YES];
        }
    
        #pragma mark ThumbImageViewDelegate methods
    
        - (void)thumbImageViewWasTapped:(ThumbImageView *)tiv {
            [self pickImageNamed:[tiv imageName]];
            [self toggleThumbView];
        }
    
        - (void)thumbImageViewStartedTracking:(ThumbImageView *)tiv {
            [thumbScrollView bringSubviewToFront:tiv];
        }
    
    
        // CONTROLS DRAGGING AND DROPPING THUMBNAILS...
    
        - (void)thumbImageViewMoved:(ThumbImageView *)draggingThumb {
    
            // check if we've moved close enough to an edge to autoscroll, or far enough away to stop autoscrolling
            [self maybeAutoscrollForThumb:draggingThumb];
    
            /* The rest of this method handles the reordering of thumbnails in the thumbScrollView. See  */
            /* ThumbImageView.h and ThumbImageView.m for more information about how this works.          */
    
            // we'll reorder only if the thumb is overlapping the scroll view
            if (CGRectIntersectsRect([draggingThumb frame], [thumbScrollView bounds])) {        
    
                BOOL draggingRight = [draggingThumb frame].origin.x > [draggingThumb home].origin.x ? YES : NO;
    
                /* we're going to shift over all the thumbs who live between the home of the moving thumb */
                /* and the current touch location. A thumb counts as living in this area if the midpoint  */
                /* of its home is contained in the area.                                                  */
                NSMutableArray *thumbsToShift = [[NSMutableArray alloc] init];
    
                // get the touch location in the coordinate system of the scroll view
                CGPoint touchLocation = [draggingThumb convertPoint:[draggingThumb touchLocation] toView:thumbScrollView];
    
                // calculate minimum and maximum boundaries of the affected area
                float minX = draggingRight ? CGRectGetMaxX([draggingThumb home]) : touchLocation.x;
                float maxX = draggingRight ? touchLocation.x : CGRectGetMinX([draggingThumb home]);
    
                // iterate through thumbnails and see which ones need to move over
                for (ThumbImageView *thumb in [thumbScrollView subviews]) {
    
                    // skip the thumb being dragged
                    if (thumb == draggingThumb) continue;
    
                    // skip non-thumb subviews of the scroll view (such as the scroll indicators)
                    if (! [thumb isMemberOfClass:[ThumbImageView class]]) continue;
    
                    float thumbMidpoint = CGRectGetMidX([thumb home]);
                    if (thumbMidpoint >= minX && thumbMidpoint <= maxX) {
                        [thumbsToShift addObject:thumb];
                    }
                }
    
                // shift over the other thumbs to make room for the dragging thumb. (if we're dragging right, they shift to the left)
                float otherThumbShift = ([draggingThumb home].size.width + THUMB_H_PADDING) * (draggingRight ? -1 : 1);
    
                // as we shift over the other thumbs, we'll calculate how much the dragging thumb's home is going to move
                float draggingThumbShift = 0.0;
    
                // send each of the shifting thumbs to its new home
                for (ThumbImageView *otherThumb in thumbsToShift) {
                    CGRect home = [otherThumb home];
                    home.origin.x += otherThumbShift;
                    [otherThumb setHome:home];
                    [otherThumb goHome];
                    draggingThumbShift += ([otherThumb frame].size.width + THUMB_H_PADDING) * (draggingRight ? 1 : -1);
                }
    
                // change the home of the dragging thumb, but don't send it there because it's still being dragged
                CGRect home = [draggingThumb home];
                home.origin.x += draggingThumbShift;
                [draggingThumb setHome:home];
            }
        }
    
        - (void)thumbImageViewStoppedTracking:(ThumbImageView *)tiv {
            // if the user lets go of the thumb image view, stop autoscrolling
            [autoscrollTimer invalidate];
            autoscrollTimer = nil;
        }
    
        #pragma mark Autoscrolling methods
    
        - (void)maybeAutoscrollForThumb:(ThumbImageView *)thumb {
    
            autoscrollDistance = 0;
    
            // only autoscroll if the thumb is overlapping the thumbScrollView
            if (CGRectIntersectsRect([thumb frame], [thumbScrollView bounds])) {
    
                CGPoint touchLocation = [thumb convertPoint:[thumb touchLocation] toView:thumbScrollView];
                float distanceFromLeftEdge  = touchLocation.x - CGRectGetMinX([thumbScrollView bounds]);
                float distanceFromRightEdge = CGRectGetMaxX([thumbScrollView bounds]) - touchLocation.x;
    
                if (distanceFromLeftEdge < AUTOSCROLL_THRESHOLD) {
                    autoscrollDistance = [self autoscrollDistanceForProximityToEdge:distanceFromLeftEdge] * -1; // if scrolling left, distance is negative
                } else if (distanceFromRightEdge < AUTOSCROLL_THRESHOLD) {
                    autoscrollDistance = [self autoscrollDistanceForProximityToEdge:distanceFromRightEdge];
                }        
            }
    
            // if no autoscrolling, stop and clear timer
            if (autoscrollDistance == 0) {
                [autoscrollTimer invalidate];
                autoscrollTimer = nil;
            } 
    
            // otherwise create and start timer (if we don't already have a timer going)
            else if (autoscrollTimer == nil) {
                autoscrollTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / 60.0)
                                                                   target:self 
                                                                 selector:@selector(autoscrollTimerFired:) 
                                                                 userInfo:thumb 
                                                                  repeats:YES];
            } 
        }
    
        - (float)autoscrollDistanceForProximityToEdge:(float)proximity {
            // the scroll distance grows as the proximity to the edge decreases, so that moving the thumb
            // further over results in faster scrolling.
            return ceilf((AUTOSCROLL_THRESHOLD - proximity) / 5.0);
        }
    
        - (void)legalizeAutoscrollDistance {
            // makes sure the autoscroll distance won't result in scrolling past the content of the scroll view
            float minimumLegalDistance = [thumbScrollView contentOffset].x * -1;
            float maximumLegalDistance = [thumbScrollView contentSize].width - ([thumbScrollView frame].size.width + [thumbScrollView contentOffset].x);
            autoscrollDistance = MAX(autoscrollDistance, minimumLegalDistance);
            autoscrollDistance = MIN(autoscrollDistance, maximumLegalDistance);
        }
    
        - (void)autoscrollTimerFired:(NSTimer*)timer {
            [self legalizeAutoscrollDistance];
    
            // autoscroll by changing content offset
            CGPoint contentOffset = [thumbScrollView contentOffset];
            contentOffset.x += autoscrollDistance;
            [thumbScrollView setContentOffset:contentOffset];
    
            // adjust thumb position so it appears to stay still
            ThumbImageView *thumb = (ThumbImageView *)[timer userInfo];
            [thumb moveByOffset:CGPointMake(autoscrollDistance, 0)];
        }
    
        #pragma mark View handling methods
    
        - (void)toggleThumbView {
            [self createSlideUpViewIfNecessary]; // no-op if slideUpView has already been created
            CGRect frame = [slideUpView frame];
            if (thumbViewShowing) {
                frame.origin.y = 0;
            } else {
                frame.origin.y = -225;
            }
    
            [UIView beginAnimations:nil context:nil];
            [UIView setAnimationDuration:0.3];
            [slideUpView setFrame:frame];
            [UIView commitAnimations];
    
            thumbViewShowing = !thumbViewShowing;
        }
    
        - (void)pickImageNamed:(NSString *)name {
    
            // first remove previous image view, if any
            [[imageScrollView viewWithTag:ZOOM_VIEW_TAG] removeFromSuperview];
    
            UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"%@.jpg", name]];
            TapDetectingImageView *zoomView = [[TapDetectingImageView alloc] initWithImage:image];
    
    
         zoomView.autoresizingMask = UIViewAutoresizingFlexibleWidth ;
    
    
            [zoomView setDelegate:self];
            [zoomView setTag:ZOOM_VIEW_TAG];
            [imageScrollView addSubview:zoomView];
            [imageScrollView setContentSize:[zoomView frame].size];
            [zoomView release];
    
            // choose minimum scale so image width fits screen
            float minScale  = [imageScrollView frame].size.width  / [zoomView frame].size.width;
            [imageScrollView setMinimumZoomScale:minScale];
            [imageScrollView setZoomScale:minScale];
            [imageScrollView setContentOffset:CGPointZero];
        }
    
        - (NSArray *)imageNames {
    
            // the filenames are stored in a plist in the app bundle, so create array by reading this plist
            NSString *path = [[NSBundle mainBundle] pathForResource:@"Images" ofType:@"plist"];
            NSData *plistData = [NSData dataWithContentsOfFile:path];
            NSString *error; NSPropertyListFormat format;
            NSArray *imageNames = [NSPropertyListSerialization propertyListFromData:plistData
                                                                   mutabilityOption:NSPropertyListImmutable
                                                                             format:&format
                                                                   errorDescription:&error];
            if (!imageNames) {
                NSLog(@"Failed to read image names. Error: %@", error);
                [error release];
            }
    
            return imageNames;
        }
    
    
    
    
        - (void)createSlideUpViewIfNecessary {
    
            if (!slideUpView) {
    
                [self createThumbScrollViewIfNecessary];
    
                CGRect bounds = [[self view] bounds];
                float thumbHeight = [thumbScrollView frame].size.height;
                float labelHeight = CREDIT_LABEL_HEIGHT;
    
                // create label giving credit for images
                UILabel *creditLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, thumbHeight, bounds.size.width, labelHeight)];
    
                [creditLabel setBackgroundColor:[UIColor clearColor]];
                [creditLabel setTextColor:[UIColor whiteColor]];
    
         // [creditLabel setFont:[UIFont fontWithName:@"Helvetica" size:16]];
         // [creditLabel setText:@"SAMPLE TEXT"];
    
                [creditLabel setTextAlignment:UITextAlignmentCenter];        
    
    
                // create container view that will hold scroll view and label
                CGRect frame = CGRectMake(0.0, -225.00, bounds.size.width+256, thumbHeight + labelHeight);
          slideUpView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
                slideUpView = [[UIView alloc] initWithFrame:frame];
                [slideUpView setBackgroundColor:[UIColor blackColor]];
                [slideUpView setOpaque:NO];
                [slideUpView setAlpha:.75];
                [[self view] addSubview:slideUpView];
    
                // add subviews to container view
                [slideUpView addSubview:thumbScrollView];
                [slideUpView addSubview:creditLabel];
                [creditLabel release];   
    
    
    
            }    
        }
    
        - (void)createThumbScrollViewIfNecessary {
    
            if (!thumbScrollView) {        
    
                float scrollViewHeight = THUMB_HEIGHT + THUMB_V_PADDING;
                float scrollViewWidth  = [[self view] bounds].size.width;
                thumbScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, scrollViewWidth, scrollViewHeight)];
                [thumbScrollView setCanCancelContentTouches:NO];
                [thumbScrollView setClipsToBounds:NO];
    
                // now place all the thumb views as subviews of the scroll view 
                // and in the course of doing so calculate the content width
                float xPosition = THUMB_H_PADDING;
                for (NSString *name in [self imageNames]) {
                    UIImage *thumbImage = [UIImage imageNamed:[NSString stringWithFormat:@"%@_thumb.jpg", name]];
                    if (thumbImage) {
                        ThumbImageView *thumbView = [[ThumbImageView alloc] initWithImage:thumbImage];
                        [thumbView setDelegate:self];
                        [thumbView setImageName:name];
                        CGRect frame = [thumbView frame];
                        frame.origin.y = THUMB_V_PADDING;
                        frame.origin.x = xPosition;
                        [thumbView setFrame:frame];
                        [thumbView setHome:frame];
                        [thumbScrollView addSubview:thumbView];
                        [thumbView release];
                        xPosition += (frame.size.width + THUMB_H_PADDING);
                    }
                }
                [thumbScrollView setContentSize:CGSizeMake(xPosition, scrollViewHeight)];
            }    
        }
    
        #pragma mark Utility methods
    
        - (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center {
    
            CGRect zoomRect;
    
            // the zoom rect is in the content view's coordinates. 
            //    At a zoom scale of 1.0, it would be the size of the imageScrollView's bounds.
            //    As the zoom scale decreases, so more content is visible, the size of the rect grows.
            zoomRect.size.height = [imageScrollView frame].size.height / scale;
            zoomRect.size.width  = [imageScrollView frame].size.width  / scale;
    
            // choose an origin so as to get the right center.
            zoomRect.origin.x    = center.x - (zoomRect.size.width  / 2.0);
            zoomRect.origin.y    = center.y - (zoomRect.size.height / 2.0);
    
            return zoomRect;
        }
    
    
        #pragma mark -
        #pragma mark Rotation support
    
        // Ensure that the view controller supports rotation and that the split view can therefore show in both portrait and landscape.
        - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
         return YES;
        }
    
    
    
    
    
    
        @end
    

1 个答案:

答案 0 :(得分:0)

如果您在Nib文件中设置了UIScrollView,请确保在旋转时正确调整大小(使用Interface Builder中的大小检查器中的自动调整控件:框内的两组箭头应为红色)

然后在iPad改变方向时使用它来重新缩放:

- (void)willAnimateSecondHalfOfRotationFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation duration:(NSTimeInterval)duration{
//if your UIImageView is called zoomView use this
CGRect zoomRect=CGRectMake(0,0,zoomView.frame.size.width, zoomView.frame.size.height);
[scrollView zoomToRect:zoomRect animated:YES];}

(对于{}的错误放置感到抱歉,但由于某种原因,它没有正确粘贴代码) 希望这有帮助!