美文网首页IOSSwifty Coding程序员
IOS UISCrollView 新手指引 (一个照片的操作)

IOS UISCrollView 新手指引 (一个照片的操作)

作者: 代号027 | 来源:发表于2015-10-08 10:55 被阅读2095次

    原文: appcoda.com (IOS Beginner's Guide to UIScrollView 由joyce echessa发布
    翻译: 安明哲
    说明: 转载时请注明出处

    在IOS中,scroll view 本用作显示屏幕上不能完全装下的内容。它主要有两个作用:

    • 用户可以通过拖动的方式显示更多内容
    • 用户可以通过手势缩放现实的内容

    IOS的公共控件UITbaleView就是继承与UIScrollView并提供了一种不错的方式去呈现内容(当这个内容大于屏幕尺寸)

    在本节课程中,我们将从多方面了解ScrollView,特性,创建一个ScrollView(通过代码和通过Interface Builder),滚动和缩放,insets和outsets。


    开始阅读之前,请首先下载本届课程的源代码。

    译者注:
    这里的下载需要自带梯子,如果没有梯子,可以从我的服务器获取

    通过编码方式创建ScrollView

    不管是通过代码或者Interface builder都可以在一个view中创建一个Scroll View,然后做一点点必要的配置就实现一个基本的ScrollView的功能了。

    • 你必须设置 ContentSize 属性,此属性用于指定你要展现的内容的Size,IOS由此确认滚动区域。
    • 你还必须添加一个或者多个View以供显示。

    当然,还有许多可选的配置,垂直或是水平滚动,滑动、缩放的效果,滚动条的路径(滚动的方向)等等。

    现在,我们开始通过代码创建一个ScrollView,打开 ScrollViewDemo(刚才下载的项目),仅仅是一个简单地Signle View,其中ScollerViewController这个类与Interface Builder中的UIViewController关联,并且此项目还包含了一张图片image.png (图片来自unsplash.com)

    打开ScrollViewController.swift 并且添加如下代码:

    var scrollView: UIScrollView!
    var imageView: UIImageView!
    

    修改 viewDidLoad() 如下:

    override func viewDidLoad() {
        super.viewDidLoad()
           
        imageView = UIImageView(image: UIImage(named: "image.png"))
            
        scrollView = UIScrollView(frame: view.bounds)
        scrollView.backgroundColor = UIColor.blackColor()
        scrollView.contentSize = imageView.bounds.size
       //译者注:如果你是用的是swift2.x 这行代码会出现问题
       scrollView.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
            
        scrollView.addSubview(imageView)
        view.addSubview(scrollView)
    }
    

    译者注
    上面的代码中带注释的一行会在swift2下报错,在swift2.0中同时取得两个枚举值不再支持使用 | 运算符,而改用数组 ,所以swift2中正确的代码应该是这个样子
    scrollView.autoresizingMask = [UIViewAutoresizing.FlexibleHeight,UIViewAutoresizing.FlexibleWidth]

    上面的代码创建了一个scroll view和一张图片。其中ImageView是ScrollView的子view(有点绕);contentSize指定了可滚动的地带为图片的大小(2000 x 1500);scrollView的背景为黑色,设置autoresizeMask为.FlexibleWidth和 .FlexibleHeight以便于在屏幕旋转的时候scrollview与parsentView维持正确位置关系。运行这个app的时候你应该能够图片的没一部分。

    当你运行的时候,你可能会注意到,通常你只能看到图片左上角的那一部分,就像下面这样:


    这是因为scrollview的bound(默认)被设置为(0,0),也就是图片的左上角。如果你希望重新定位第打开app时图片的显示位置,你需要改变scrollview的bound,SrollerView有一个contentOffset属性可以帮助你实现这个需求。

    添加如下代码到你的代码中,(注意这段代码应该在autoresizingMask之后):

    scrollView.contentOffset = CGPoint(x: 1000, y: 450)
    

    这个时候再次运行app你将看到scrollview已经移动到图皮的另一部分,这样当view被加载的时候,你就可以确定你要给用户呈现什么。

    缩放

    我们已经创建了一个scrollview并且允许用户通过滚动来控制一个较大尺寸的view,但是如果视图可以缩放,将进一步增强用户体验。

    要支持缩放,你必须为view添加一个delegate,这个delegate必须遵从IScrollViewDelegate这个协议,并且必须要实现viewForZoomingInScrollView(),该方法返回一个view,这个view将可以在scrollview内缩放。

    你依旧要做一点点的工作来支持缩放,你可以设置scrollvierw的 minimumZoomScale 和 maximumZoomScale属性(如果不设定这两个属性,他们将会有一个默认值-->1.0)

    修改ScrollerView的定义如下:

    class ScrollViewController: UIViewController, UIScrollViewDelegate
    

    然后添加如下方法到类中:

    func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
            return imageView
        }
    

    最后,添加如下代码到viewDidLoad()的底部:
    译者注:主要就是绑定delegate,设置缩放的范围和步长

    scrollView.delegate = self
    scrollView.minimumZoomScale = 0.1
    scrollView.maximumZoomScale = 4.0
    scrollView.zoomScale = 1.0
    

    上面的代码中设置了zoomScale为1.0用于指定最大缩放和最小缩放的缩放因子(默认情况下缩放的大小),当你运行app,你可以滚动并且缩放,我们设置最大缩放比例4.0,所以你最大可以放大这张图片到原始尺寸的4倍(最小缩放比例同理),但是当我们把图片放大的时候,图片会变得很很模糊,这并不是用户想要看到的,下一步中我们将让图片返回到1.0初始的状态。

    在上边,我们设置minimumZoomScale为0.1以至于缩小之后返回一个很小的图片并且屏幕中出现了很多空白。我们想让图片自适应

    要实现这个功能,我们需要根据scrollview的size和imageview的size计算最小缩放比例。

    首先删除viewDidLoad里面的几行代码:

    scrollView.minimumZoomScale = 0.1
    scrollView.maximumZoomScale = 4.0
    scrollView.zoomScale = 1.0
    

    添加一个方法到类中,我们得到的宽度和高度的比例,并选择较小的两者,并设置为minimumScale。提示一下,我们删除了maxinmumZoomScale,所以他会被默认设置为1.0.

    func setZoomScale(){
            let imageViewSize = imageView.bounds.size
            let scrollViewSize = scrollView.bounds.size
            let widthSacle = scrollViewSize.width / imageViewSize.width
            let heightSacle = scrollViewSize.height / imageViewSize.height
            
            scrollView.minimumZoomScale = min(widthSacle, heightSacle)
            scrollView.zoomScale = 1.0
        }
    

    然后再viewDidLoad()中调用这个方法

    setZoomScale()
    

    同时添加以下代码,以便在设备方向改变后图像依旧铺满屏幕。

        override func viewWillLayoutSubviews() {
            setZoomScale()
        }
    
    


    从上面的图片中,你可能会注意到,图片的位置在屏幕左上角,我们想改变他到屏幕的中心。

    添加如下方法到类中:

    func scrollViewDidZoom(scrollView: UIScrollView) {
        let imageViewSize = imageView.frame.size
        let scrollViewSize = scrollView.bounds.size
            
        let verticalPadding = imageViewSize.height < scrollViewSize.height ? (scrollViewSize.height - imageViewSize.height) / 2 : 0
        let horizontalPadding = imageViewSize.width < scrollViewSize.width ? (scrollViewSize.width - imageViewSize.width) / 2 : 0
            
        scrollView.contentInset = UIEdgeInsets(top: verticalPadding, left: horizontalPadding, bottom: verticalPadding, right: horizontalPadding)
    }
    

    这个方法会在每次一缩放操作后执行,它告诉delegate,scrllowView的缩放比例发生了改变,上面的代码计算了padding并且根据padding重新设置了scrollview 内容的padding

    此时,运行app缩放到最小是 将得到如下效果

    通过连按缩放

    默认情况下ScrollView通过少量的代码即可实现支持缩放(捏和撑)手势,但是支持更多的手势我们则需要再做一些工作。

    IOS人机交互的借口定义了一种通过双击(连按)来进行缩放的方法。但是这个方法认为view的缩放级别是单一的(翻译起来有点绕)总之就是双击一次执行了放大操作后下一次会默认执行缩小操作。但是很多程序的交互行为是需要更灵活的双击缩放的,比如地图应用,需要不停地双击放大,而不是放大后再双击变成缩小。

    在我们app中,我们将实现double-tap 把图片放到最大,而后双击再缩小

    添加如下代码到类中:

    func setupGestureRecognizer() {
        let doubleTap = UITapGestureRecognizer(target: self, action: "handleDoubleTap:")
        doubleTap.numberOfTapsRequired = 2
        scrollView.addGestureRecognizer(doubleTap)
    }
        
    func handleDoubleTap(recognizer: UITapGestureRecognizer) {
            
        if (scrollView.zoomScale > scrollView.minimumZoomScale) {
            scrollView.setZoomScale(scrollView.minimumZoomScale, animated: true)
        } else {
            scrollView.setZoomScale(scrollView.maximumZoomScale, animated: true)
        }
    }
    

    然后再viewDidLoad底部调用他们:

    setupGestureRecognizer()
    

    在上面的代码中,我们添加了一个gesture recognize(手势识别器),当用户双击之后,我们可以根据当前的缩放级别来进行放大和缩小。
    这样,我们就可以通过双击放大和缩小图片了。

    相关文章

      网友评论

      • Eunicon:能不能把iOS的名字写对
        代号027:@Eunicon 确实没太注意到这个问题,早先学习CSICO设备的时候也碰到过真正的IOS,但是,我觉得不用太care这个。
      • 代号027:scrollViewSize.width / imageViewSize.width
        如果现在scrollView的宽度是800 图片的宽度是1600 是不是要让图片按照(800/1600 = 0.5)的倍率缩放刚好让图片的宽度等于scrollview的宽度
        那么高度也是一样的道理

        现在有一张图片 2000 * 3000 的尺寸 scrollview的大小是500*1000
        那么如果按照宽度缩放 那么最小缩放倍率是不是应该是 500/2000=0.25 倍 刚好宽度适应 此时图片缩放0.25倍 缩放后图片的高度是 3000*0.25 750 最终缩放后图片尺寸是 500*750
        如果按照高度缩放 那么最小缩放倍率为 1000/3000=0.3倍 高度刚好等于屏幕高度 此时图片缩放0.3倍 缩放后图片的宽度是 500*0.3=150 最终得到的图片大小是 150*1000

        想一下 500*750 和 150*1000 的区别 就明白 我们需要使用最短的尺寸来做图片的缩小咯

        所以 设置最小的缩放倍率的时候使用了min()函数,取最小的倍率

        scrollView.minimumZoomScale = min(widthSacle, heightSacle)

      本文标题:IOS UISCrollView 新手指引 (一个照片的操作)

      本文链接:https://www.haomeiwen.com/subject/fyrncttx.html