zoukankan      html  css  js  c++  java
  • iphone下scrollview图片浏览器小记

    今天看书中介绍了从图片库中调用图片的例子,一时性起打算做一个简单的图片浏览器。

    功能很简单,从图片库中载入图片,然后放到view下,并支持放大,缩小,平移。

    由于对控件库不了解,一开始的方案是这样的:

    前面的框架都一样:

    用toolbar做按钮条,里面有个按键,触发从按键。

    按键action调用图片库,之后图片库发消息到delegate(我这里协议挂在了主UIViewController上面,后面其他的delegate也一样)。

    如果正确得到了图片 UIImagePickerControllerDelegate的imagePickerController:didFinishPickingMediaWithInfo:的第二个参数可以得到一个包含选定图片的Dictionary。

    OK,演出开始了。后面的方案是这样。

    1.  搞了个UIImageView作为图片载体,扑满整个屏幕,然后将Mode设置为Center,图片设置后可以居中显示。

         然后利用UIPinchGestureRecognizer做手势,手势触发后会回调响应方法。在方法中设置UIImageView的bounds和center保证其居中显示。过程中从网络上搜索了一个扩展UIImage的类型,可以进行缩放图片。源码:(注意,这个函数由于用到了UIGraphicsXXXX函数,要求只能再主线程中调用)

        

    //
    //  UIImage_Extra.h
    //  Camera
    //
    //  Created by 李 择一 on 11-4-22.
    //  Copyright 2011 __MyCompanyName__. All rights reserved.
    //

    #import 
    <Foundation/Foundation.h>


    @interface UIImage (Extra)

    - (UIImage*) imageByScalingAndCroppingForSize: (CGSize)targetSize;

    @end

    //
    //  UIImage_Extra.m
    //  Camera
    //
    //  Created by 李 择一 on 11-4-22.
    //  Copyright 2011 __MyCompanyName__. All rights reserved.
    //

    #import 
    "UIImage_Extra.h"


    @implementation UIImage (Extra)

    - (UIImage*)imageByScalingAndCroppingForSize: (CGSize)targetSize
    {
        UIImage 
    *sourceImage = self;
        UIImage 
    *newImage = nil;        
        CGSize imageSize 
    = sourceImage.size;
        CGFloat width 
    = imageSize.width;
        CGFloat height 
    = imageSize.height;
        CGFloat targetWidth 
    = targetSize.width;
        CGFloat targetHeight 
    = targetSize.height;
        CGFloat scaleFactor 
    = 0.0;
        CGFloat scaledWidth 
    = targetWidth;
        CGFloat scaledHeight 
    = targetHeight;
        CGPoint thumbnailPoint 
    = CGPointMake(0.0,0.0);
        
        
    if (CGSizeEqualToSize(imageSize, targetSize) == NO) 
        {
            CGFloat widthFactor 
    = targetWidth / width;
            CGFloat heightFactor 
    = targetHeight / height;
            
            
    if (widthFactor > heightFactor) 
                scaleFactor 
    = widthFactor; // scale to fit height
            else
                scaleFactor 
    = heightFactor; // scale to fit width
            scaledWidth  = width * scaleFactor;
            scaledHeight 
    = height * scaleFactor;
            
            
    // center the image
            if (widthFactor > heightFactor)
            {
                thumbnailPoint.y 
    = (targetHeight - scaledHeight) * 0.5
            }
            
    else 
                
    if (widthFactor < heightFactor)
                {
                    thumbnailPoint.x 
    = (targetWidth - scaledWidth) * 0.5;
                }
        }       
        
        UIGraphicsBeginImageContext(targetSize); 
    // this will crop
        
        CGRect thumbnailRect 
    = CGRectZero;
        thumbnailRect.origin 
    = thumbnailPoint;
        thumbnailRect.size.width  
    = scaledWidth;
        thumbnailRect.size.height 
    = scaledHeight;
        
        [sourceImage drawInRect:thumbnailRect];
        
        newImage 
    = UIGraphicsGetImageFromCurrentImageContext();
        
    if(newImage == nil) 
            NSLog(
    @"could not scale image");
        
        
    //pop the context to get back to the default
        UIGraphicsEndImageContext();
        
    return newImage;
    }


    @end

       再往下做平移的时候出现了问题,虽然可以重载touchesBegan和touchesMove移动UIImageView,可是就失去了iOS特效了,并且当图片移到屏幕边缘再进行放大,缩小,UIImageView就不一定飞到那里去了,还需要继续增加判断条件。所以此方法不可取。

     ------------------------------2011-04-25 更新------------------------------

    现在发现了新的api可以解决拉伸的问题。在UIImage 中有个函数叫stretchableImageWithLeftCapWidth:topCapHeight:的,可以返回一个新的UIImage,这个UIImage是可以拉伸的。具体用法请参阅apple的Sample Code.

    -------------------------------------------------------------------------------

    2.  到网上查了可以利用UIScrollView做平移处理,在其中嵌入一个UIImageView,手势用来管理图片放大缩小,这样就可以一边吃火锅,一边唱歌了。

       这个方案要考虑的事情有几个,一个是UIScrollView的contentSize的要考虑UIImageView的大小,在放大或者缩小图片以后要调整contentSize的大小。

        还有一个就是在缩放的时候要考虑到,缩放的中心位置问题。比如,现在图片上有个人脸,然后手势是以人脸鼻子为中心放大的,在放大结束后,可能手势的中心就跑偏了,因此要在缩放时修改UIImageView的center,这个计算还是挺复杂的。

    3.  为了解决这个问题继续搜索文档,发现在UIScrollView里面有zoom这个东东,可以通过delegate的viewForZoomingInScrollView:方法指定UIScrollView中的某个view放大,还可以设定放大的最大倍数和最小倍数。这个nb了,一个UIScrollView类全都搞定了平移缩放。酷啊!!

       但是这个也有要注意的问题。由于UIScrollView里面可能要主动调用他所包含subView的属性,因此在缩放过程中,不要修改subview的属性。

            另外,缩放平移全都人家搞了,在给UIImageView中换图片之前一定要注意先将UIScrollView的zoomScale,contentSize,contentOffset全都设置成初始值。设想这样一个情况,在UIScrollView里面将图片放大,contentSize,contentOffset,zoomScale全变了,而你这时候找了个特小的图片放进来,如果不设置那三个属性的初值,或者只设置了一个,这样必然会造成混乱。

    三种方法里还是第三种最简单啊。

    总结:我忘了那本书里面说过,Apple公司为在Mac上面的工作做了20年,如果你需要用很多代码实现一个很简单的功能,肯定是方法不对。

    今天的探索印证了这句话。还有,现在市面上所有的iOS开发书籍里都没有原理层面的讲解开发的。所以搜索引擎,加上浏览各种网站论坛成为解决问题的快捷途径。

    不知道什么时候能出一本《深入理解iOS开发模型》之类的书啊!!

     

  • 相关阅读:
    LeetCode 40. 组合总和 II(Combination Sum II)
    LeetCode 129. 求根到叶子节点数字之和(Sum Root to Leaf Numbers)
    LeetCode 60. 第k个排列(Permutation Sequence)
    LeetCode 47. 全排列 II(Permutations II)
    LeetCode 46. 全排列(Permutations)
    LeetCode 93. 复原IP地址(Restore IP Addresses)
    LeetCode 98. 验证二叉搜索树(Validate Binary Search Tree)
    LeetCode 59. 螺旋矩阵 II(Spiral Matrix II)
    一重指针和二重指针
    指针的意义
  • 原文地址:https://www.cnblogs.com/biosli/p/2025224.html
Copyright © 2011-2022 走看看