国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

深入理解iOS開發(fā)中的UIScrollView

移動開發(fā) iOS
感謝UIKit的坐標系統(tǒng)特性,使我們之花了30幾行代碼就能重現(xiàn)UIScrollView的精華,當然真正的UIScrollView要比我們所做的復雜的多,反彈效果,動量滾動,放大試圖,還有代理方法,這些特性我們沒有在這里涉及到。

我是Mike Ash的Let’s Build…系列文章的忠實粉絲,在這一系列文章中他從頭設計Cocoa的控件來解釋他們的工作原理。在這里我要做一點類似的事情,用幾行代碼來實現(xiàn)我自己的滾動試圖。不過首先,讓我們先來了解一下UIKit中的坐標系是怎么工作的。如果你只對滾動試圖的代碼實現(xiàn)感興趣可以放心跳過下一小節(jié)。UIKit坐標系每一個View都定義了他自己的坐標系統(tǒng)。如下圖所示,x軸指向右方,y軸指向下方:

注意這個邏輯坐標系并不關注包含在其中View的寬度和高度。整個坐標系沒有邊界向四周無限延伸.我們在坐標系中放置四個子View。每一次色塊代表一個View:

添加View的代碼實現(xiàn)如下:

  1. UIView *redView = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 100, 100)]; 
  2. redView.backgroundColor = [UIColor colorWithRed:0.815 green:0.007 
  3.     blue:0.105 alpha:1]; 
  4.   
  5. UIView *greenView = [[UIView alloc] initWithFrame:CGRectMake(150, 160, 150, 200)]; 
  6. greenView.backgroundColor = [UIColor colorWithRed:0.494 green:0.827 
  7.     blue:0.129 alpha:1]; 
  8.   
  9. UIView *blueView = [[UIView alloc] initWithFrame:CGRectMake(40, 400, 200, 150)]; 
  10. blueView.backgroundColor = [UIColor colorWithRed:0.29 green:0.564 
  11.     blue:0.886 alpha:1]; 
  12.   
  13. UIView *yellowView = [[UIView alloc] initWithFrame:CGRectMake(100, 600, 180, 150)]; 
  14. yellowView.backgroundColor = [UIColor colorWithRed:0.972 green:0.905 
  15.     blue:0.109 alpha:1]; 
  16.   
  17. [mainView addSubview:redView]; 
  18. [mainView addSubview:greenView]; 
  19. [mainView addSubview:blueView]; 
  20. [mainView addSubview:yellowView]; 

bounds

Apple關于UIView的文檔中是這樣描述bounds屬性的:

bounds矩形…描述了該視圖在其自身坐標系中的位置和大小。

一個View可以被看作是定義在其所在坐標系平面上的一扇窗戶或者說是一個矩形的可視區(qū)域。View的邊界表明了這個矩形可視區(qū)域的位置和大小。

假設我們的View寬320像素,高480像素,原點在(0,0)。那么這個View就變成了整個坐標系平面的觀察口,它展示的只是整個平面的一小部分。位于該View邊界外的區(qū)域依然存在,只是被隱藏起來了。

一個View提供了其所在平面的一個觀察口。View的bounds矩形描述了這個可是區(qū)域的位置和大小。

Frame

接下來我們來試著修改bounds的原點坐標:

  1. CGRect bounds = mainView.bounds; 
  2. bounds.origin = CGPointMake(0, 100); 
  3. mainView.bounds = bounds; 

當我們把bound原點設為(0,100)后,整個畫面看起來就像這樣:

修改bounds的原點就相當與在平面上移動這個可視區(qū)域。

看起來好像是這個View向下移動了100像素,在這個View自己的坐標系中這確實沒錯。不過這個View真正位于屏幕上的位置(更準確的說在其父View上的位置)其實沒有改變,因為這是由View的frame屬性決定的,它并沒有改變:

frame矩形…定義了這個View在其父View坐標系中的位置和大小。

由于View的位置是相對固定的,你可以把整個坐標平面想象成我們可以上下拖動的透明幕布,把這個View想象成我們觀察坐標平面的窗口。調整View的Bounds屬性就相當于拖動這個幕布,那么下方的內容就能在我們View中被觀察到:

Since the view’s position is fixed (from its own perspective), think of the coordinate system plane as a piece of transparent film we can drag around, and of the view as a fixed window we are looking through. Adjusting the bounds’s origin is equivalent to moving the transparent film such that another part of it becomes visible through the view:

A standard x/y coordinate system with the x-axis pointing right and the y-axis pointing down

修改bounds的原點坐標也相當于把整個坐標系向上拖動,因為View的frame沒由變過,所以它相對于父View的位置沒有變化過。

其實這就是UIScrollView滑動時所發(fā)生的事情。注意從一個用戶的角度來看,他以為時這個View中的子View在移動,其實他們的在坐標系中位置(他們的frame)沒有發(fā)生過變化。

打造你的UIScrollView

一個scroll view并不需要其中子View的坐標來使他們滾動。***要做的就是改變他的bounds屬性。知道了這一點,實現(xiàn)一個簡單的scroll view就沒什么困難了。我們用一個gesture recognizer來識別用戶的拖動操作,根據(jù)用戶拖動的偏移量來改變bounds的原點:

  1. // CustomScrollView.h 
  2. @import UIKit; 
  3.   
  4. @interface CustomScrollView : UIView 
  5.   
  6. @property (nonatomic) CGSize contentSize; 
  7.   
  8. @end 
  9.   
  10. // CustomScrollView.m 
  11. #import "CustomScrollView.h" 
  12.   
  13. @implementation CustomScrollView 
  14.   
  15. - (id)initWithFrame:(CGRect)frame 
  16.     self = [super initWithFrame:frame]; 
  17.     if (self == nil) { 
  18.         return nil; 
  19.     } 
  20.     UIPanGestureRecognizer *gestureRecognizer = [[UIPanGestureRecognizer alloc] 
  21.         initWithTarget:self action:@selector(handlePanGesture:)]; 
  22.     [self addGestureRecognizer:gestureRecognizer]; 
  23.     return self; 
  24.   
  25. - (void)handlePanGesture:(UIPanGestureRecognizer *)gestureRecognizer 
  26.     CGPoint translation = [gestureRecognizer translationInView:self]; 
  27.     CGRect bounds = self.bounds; 
  28.   
  29.     // Translate the view's bounds, but do not permit values that would violate contentSize 
  30.     CGFloat newBoundsOriginX = bounds.origin.x - translation.x; 
  31.     CGFloat minBoundsOriginX = 0.0; 
  32.     CGFloat maxBoundsOriginX = self.contentSize.width - bounds.size.width; 
  33.     bounds.origin.x = fmax(minBoundsOriginX, fmin(newBoundsOriginX, maxBoundsOriginX)); 
  34.   
  35.     CGFloat newBoundsOriginY = bounds.origin.y - translation.y; 
  36.     CGFloat minBoundsOriginY = 0.0; 
  37.     CGFloat maxBoundsOriginY = self.contentSize.height - bounds.size.height; 
  38.     bounds.origin.y = fmax(minBoundsOriginY, fmin(newBoundsOriginY, maxBoundsOriginY)); 
  39.   
  40.     self.bounds = bounds; 
  41.     [gestureRecognizer setTranslation:CGPointZero inView:self]; 
  42.   
  43. @end 

和真正的UIScrollView一樣,我們的類也有一個contentSize屬性,你必須從外部來設置這個值來指定可以滾動的區(qū)域,當我們改變bounds的大小時我們要確保設置的值是有效的。

結果:

A standard x/y coordinate system with the x-axis pointing right and the y-axis pointing down

我們的scroll view已經能夠工作了,不過還缺少動量滾動,反彈效果還有滾動提示符。

總結

感謝UIKit的坐標系統(tǒng)特性,使我們之花了30幾行代碼就能重現(xiàn)UIScrollView的精華,當然真正的UIScrollView要比我們所做的復雜的多,反彈效果,動量滾動,放大試圖,還有代理方法,這些特性我們沒有在這里涉及到。

更新 5/ 2, 2014: 本文的代碼在https://github.com/ole/CustomScrollView。

更新 5/ 8, 2014:

1.坐標系并非無限延伸的。坐標系的范圍由CGFloat的長度來決定,根據(jù)32位和64位系統(tǒng)有所不同,通常來講這是一個很大的值。

2.事實上,除非你設置clipToBounds == YES,所有子View超出的部分其實仍然是可見的。只是View不會再去檢測超出部分的觸摸事件而已。

原文鏈接: Ole Begemann   翻譯:袁欣

譯文鏈接: http://blog.jobbole.com/70143/

責任編輯:閆佳明 來源: blog.jobbole
相關推薦

2012-11-22 13:02:24

jQuery插件Web

2024-07-18 10:12:04

2018-07-09 15:11:14

Java逃逸JVM

2020-12-16 09:47:01

JavaScript箭頭函數(shù)開發(fā)

2016-08-31 15:50:50

PythonThreadLocal變量

2023-10-08 08:53:36

數(shù)據(jù)庫MySQL算法

2010-06-28 10:12:01

PHP匿名函數(shù)

2020-07-21 08:26:08

SpringSecurity過濾器

2010-06-01 15:25:27

JavaCLASSPATH

2016-12-08 15:36:59

HashMap數(shù)據(jù)結構hash函數(shù)

2015-07-30 10:04:43

viewport前端

2013-11-05 13:29:04

JavaScriptreplace

2013-06-20 10:25:56

2012-11-22 10:11:16

LispLisp教程

2016-08-31 15:41:19

PythonThreadLoca變量

2016-11-07 21:59:52

threadpython

2022-02-14 07:47:26

overlayfsdockerrootfs

2022-03-25 09:01:16

CSS溢出屬性

2009-09-25 09:14:35

Hibernate日志

2013-09-22 14:57:19

AtWood
點贊
收藏

51CTO技術棧公眾號

福利片在线免费观看| 国产二区不卡| 91美女视频网站| 欧亚一区二区| 欧美午夜小视频| 久久久国产精品x99av| 99久久精品99国产精品| 99只有精品| av动漫在线观看| 欧美r片在线| 另类少妇人与禽zozz0性伦| 成人美女视频在线观看| 精品国产第一福利网站| 拔插拔插海外华人免费| 久久天天躁狠狠躁夜夜躁2014| 91视频在线看| 盗摄牛牛av影视一区二区| 亚洲高清免费在线观看| 国产精品91在线观看| 欧美性xxxx极品hd满灌| 野花国产精品入口| 免费电影视频在线看| 国产精品一区在线免费观看| 日韩在线免费av| 欧美激情一二三区| 欧美色就是色| 日韩av中文| 一区二区三区四区视频在线| 中日韩美女免费视频网站在线观看 | 黑人精品欧美一区二区蜜桃| 国产亚洲一区二区手机在线观看 | 欧美大片黄色| 99久久国产综合精品五月天喷水| 色综合色综合网色综合| 午夜精品国产更新| 久久中文在线| av国产精品| 伊人色综合网| 在线无限看免费粉色视频| 美日韩精品视频免费看| 婷婷丁香激情综合| 日本成人中文字幕在线视频 | 免费精品视频在线| 99久久这里有精品| 作爱视频免费观看视频在线播放激情网| 成人动漫在线观看视频| 日韩精品在线观看一区| 91蜜桃在线观看| 久久一区二区三区电影| 9999在线视频| 成人女性文胸| 欧美午夜精品久久久久免费视 | 日韩视频二区| 国产精品天堂蜜av在线播放| 午夜影院免费看| 亚洲v日韩v欧美v综合| 欧美激情第1页| 欧美午夜在线观看| 成人在线一区二区三区| 精品国产乱码久久久久久蜜坠欲下| 日本中文字幕在线观看| 免费看又黄又无码的网站| 国产精品影院在线观看| 亚洲精品一区在线观看香蕉| 亚洲伦理在线精品| 热久久国产精品| 久久激情av| 欧美人与牲禽动交com| 羞羞的视频免费| 亚洲欧洲一区二区| 国产精品久久久久久亚洲调教| 亚洲老头老太hd| 亚洲成av人综合在线观看| 国产精品一区久久久久| 欧美在线免费一级片| 国产精品一区二区精品视频观看| av一区在线观看| 日韩av卡一卡二| 久久av秘一区二区三区| 国产欧美日韩中文| 精品国产视频在线| 欧美精品亚洲二区| 亚洲色图视频网| 成人一区在线观看| 免费中文字幕日韩欧美| 国产中文精品久高清在线不| 国产亚洲精彩久久| 好吊日视频在线观看| 爽爽免费视频| 日本精品免费在线观看| 日韩久久不卡| 91精品中国老女人| 欧美精品久久久久久久免费观看| 亚洲国产精品推荐| 欧美午夜精品久久久久久久| 久久午夜老司机| 久久国产人妖系列| 亚洲人体大胆视频| 久久日文中文字幕乱码| 美女av一区| 九九久久国产| 久久男人av资源站| 中文字幕在线观看日本| 性疯狂做受xxxx高清视频| 狠狠热免费视频| 国产午夜精品视频一区二区三区| 欧美极品视频一区二区三区| 亚洲一区精品电影| 国产精品福利片| 性亚洲最疯狂xxxx高清| 日韩中文字幕国产| 亚洲精品小视频在线观看| 欧美一区二区视频免费观看| 色哟哟一区二区在线观看| 18涩涩午夜精品.www| 久久夜色精品一区| 不卡av在线免费观看| 国产在线视频不卡二| 日韩精品欧美成人高清一区二区| 欧美三级视频| 亚洲成av人片一区二区密柚| 欧美日韩在线二区| 亚洲涩涩av| 亚洲8888| 久久99国内| 日韩电影在线观看完整免费观看| 日韩影片在线观看| 日本中文字幕视频一区| av在线私库| av在线视屏| 国产在线天堂www网在线观看| 污视频网站免费在线观看| 黄色网在线免费看| www日韩tube| 日本成人在线播放| 国产原创精品视频| 日本片在线看| √8天堂资源地址中文在线| 日本资源在线| 黑人精品视频| 麻豆免费在线| 中文在线资源| 91精品xxx在线观看| 日本一区二区电影| 成人动漫视频在线观看| 97品白浆高清久久久久久| 亚洲精品黑牛一区二区三区| 伊人www22综合色| 国产精品调教| 免费观看不卡av| 久久在线视频免费观看| 午夜精品电影| 欧美一级视频| 麻豆精品新av中文字幕| 国产精品一品二品| 91色九色蝌蚪| 亚洲人成网站影音先锋播放| 午夜精品久久久久久久久| 色综合久久综合| 欧美日韩五月天| 亚洲黄色在线看| 最近日韩中文字幕中文| 久久久久这里只有精品| 奇米一区二区三区四区久久| 成人黄色av网站| 久久av一区二区| 中文字幕欧美日韩一区二区| 国产 日韩 亚洲 欧美| 97在线免费| 青青草视频免费在线观看| 在线中文字幕第一页| 欧美电影免费观看| 97久久精品| 欧美成人久久| 麻豆精品在线看| 久久久亚洲国产美女国产盗摄| 亚洲乱码中文字幕综合| 欧美三区免费完整视频在线观看| 亚洲高清一区二| 久久婷婷国产麻豆91天堂 | 国产精品水嫩水嫩| 亚洲一区二区偷拍精品| 欧美色综合网站| 一区二区三区动漫| 欧美一级bbbbb性bbbb喷潮片| 超碰97在线人人| 裸体裸乳免费看| 国产精品无码av无码| 未来日记在线观看| 黄色18在线观看| 亚洲春色h网| 另类亚洲自拍| 99久久精品国产一区二区三区| 亚洲另类中文字| 91精品国产高清一区二区三区| 一本色道久久综合狠狠躁篇的优点| 国产91精品久久久久久| 久草热久草热线频97精品| 97超碰青青草| 国模吧精品人体gogo|