ios UIScrollView 基础属性
?
轉
UIScrollView 原理
??? 在滾動過程當中,其實是在修改原點坐標。當手指觸摸后, scroll view會暫時攔截觸摸事件,使用一個計時器。假如在計時器到點后沒有發生手指移動事件,那么 scroll view 發送 tracking events 到被點擊的 subview。假如在計時器到點前發生了移動事件,那么 scroll view 取消 tracking 自己發生滾動。
??? 子類可以重載
touchesShouldBegin:withEvent:inContentView: 決定自己是否接收 touch 事件
pagingEnabled:當值是 YES 會自動滾動到 subview 的邊界,默認是NO
touchesShouldCancelInContentView: 開始發送 tracking messages 消息給 subview 的時候調用這個方法,決定是否發送 tracking messages 消息到subview。假如返回 NO,發送。YES 則不發送。
假如 canCancelContentTouches屬性是NO,則不調用這個方法來影響如何處理滾動手勢。
??? scroll view 還處理縮放和平移手勢,要實現縮放和平移,必須實現委托 viewForZoomingInScrollView:、scrollViewDidEndZooming:withView:atScale:
兩個方法。另外 maximumZoomScale和minimumZoomScale 兩個屬性要不一樣。
幾個屬性介紹
tracking
當 touch 后還沒有拖動的時候值是YES,否則NO
zoomBouncing
當內容放大到最大或者最小的時候值是 YES,否則 NO
zooming
當正在縮放的時候值是 YES,否則 NO
decelerating
當滾動后,手指放開但是還在繼續滾動中。這個時候是 YES,其它時候是 NO
decelerationRate
設置手指放開后的減速率
maximumZoomScale
一個浮點數,表示能放最大的倍數
minimumZoomScale?
一個浮點數,表示能縮最小的倍數
pagingEnabled
當值是 YES 會自動滾動到 subview 的邊界。默認是NO
scrollEnabled
決定是否可以滾動
delaysContentTouches
是個布爾值,當值是 YES 的時候,用戶觸碰開始,scroll view要延遲一會,看看是否用戶有意圖滾動。假如滾動了,那么捕捉 touch-down 事件,否則就不捕捉。假如值是NO,當用戶觸碰, scroll view 會立即觸發 touchesShouldBegin:withEvent:inContentView:,默認是 YES
canCancelContentTouches
當值是 YES 的時候,用戶觸碰后,然后在一定時間內沒有移動,scrollView 發送 tracking events,然后用戶移動手指足夠長度觸發滾動事件,這個時候,scrollView 發送了 touchesCancelled:withEvent: 到 subview,然后 scroView 開始滾動。假如值是 NO,scrollView 發送 tracking events 后,就算用戶移動手指,scrollView 也不會滾動。
contentSize
里面內容的大小,也就是可以滾動的大小,默認是0,沒有滾動效果。
showsHorizontalScrollIndicator
滾動時是否顯示水平滾動條
showsVerticalScrollIndicator
滾動時是否顯示垂直滾動條
bounces
默認是 yes,就是滾動超過邊界會反彈有反彈回來的效果。假如是 NO,那么滾動到達邊界會立刻停止。
bouncesZoom
和 bounces 類似,區別在于:這個效果反映在縮放上面,假如縮放超過最大縮放,那么會反彈效果;假如是 NO,則到達最大或者最小的時候立即停止。
directionalLockEnabled
默認是 NO,可以在垂直和水平方向同時運動。當值是 YES 時,假如一開始是垂直或者是水平運動,那么接下來會鎖定另外一個方向的滾動。 假如一開始是對角方向滾動,則不會禁止某個方向
indicatorStyle
滾動條的樣式,基本只是設置顏色。總共3個顏色:默認、黑、白
scrollIndicatorInsets
設置滾動條的位置
//基本屬性 //設置UIScrollView滾動的位置 @property(nonatomic) CGPoint contentOffset; //設置UIScrollView內容的尺寸,滾動范圍 @property(nonatomic) CGSize contentSize; //設置UIScrollView的4周增加額外的滾動區域 @property(nonatomic) UIEdgeInsets contentInset; //設置UIScrollView是否需要彈簧效果 @property(nonatomic) BOOL bounces;//設置UIScrollView是否能滾動 @property(nonatomic,getter=isScrollEnabled) BOOL scrollEnabled; //設置UIScrollView是否顯示水平滾動條 @property(nonatomic) BOOL showsHorizontalScrollIndicator;//設置UIScrollView是否顯示垂直滾動條 @property(nonatomic) BOOL showsVerticalScrollIndicator;?
?
?
scrollview里面的view拖動的問題
請教一下各位一個問題:我現在在一個scrollview上排列了很多view,這個scrollview是可以滾動的,我還想拖動view,但 是問題出現了,如果scrollview只能垂直滾動的話,橫向拖動view是沒問題的,但是豎向拖動view就會導致scrollview滾動,而本意 要移動的view卻不動了. scrollview不響應用戶觸摸的話,它自己就不能拖動了吧?我的目的是它也能動,但是其他view動的時候他不能動
解決了,在touchbegain中禁止scrollview滾動,然后在touchend中開啟scrollview滾動
?
- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view;??
......
今天實驗了一次,scrollview默認就是這么實現的,所以我不用自己重寫這個方法,
scrollview的工作原理是:當手指觸摸后, scroll view會暫時攔截觸摸事件,使用一個?計時器,假如在計時器到點后,沒有發生手指移動事件,?那么,scroll view發送tracking events到被點擊的subview,?假如在計時器到點前,發生了移動事件,那么 scroll view 取消tracking?自己發生滾動.?
我最后的解決辦法很無語,在touchbegain中,禁止scrollview的滾動,在touchend中打開scrollview的滾動
我的源代碼涉及到的東西比較多,不好剝離出來,我給你大概描述一下吧
//--------------初始化各個view--------------
UIScrollView *_scrollview = [[UIScrollView alloc] init];
//自定義的view,放到scrollview上
//其實正常的view就可以加到scrollview上,我之所以要自定義這么一個中間view,是因為我要重寫touch的所有方法
//重寫touch方法的原因是,我要在touchBegain中讓scrollview的滾動失效,而在touchEnd中讓滾動有效
UIMyView *_myView=[[UIMyView alloc] init];
//需要拖動的view
UIView *_view = [[UIView alloc] init];
[_myView addSubview:_view];//將view加入自定義的view中,
[_scrollview addSubview:_myView];//將自定義view加入scrollview中
//-----------------------------------------------------
//-----------MyView中的方法,其他部分我就不寫了,只關注touch方法-------------------
....
#pragma mark -- #pragma mark touch - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { .....你自己的代碼......UITouch *touch = [touches anyObject];//如果是主view,則不進行操作 if ([touch view]==self) {return; }//由于中間隔了一層自定義的view,所以要兩次superview UIScrollView *_scrollview = (UIScrollView *)[[[touch view] superview] superview]; _scrollview.scrollEnabled=NO;//讓scrollview停止響應滾動 .....你自己的代碼...... }- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { .....你自己的代碼...... UITouch *touch = [touches anyObject];UIScrollView *_scrollview = (UIScrollView *)[[[touch view] superview] superview]; _scrollview.scrollEnabled=YES;//讓scrollview可以響應滾動 .....你自己的代碼...... }
-----------------------------------------------
UIScrollView 代理(delegate)
UIScrollView在滾動過程中 或者 停止滾動 時,如果需要做一些特定的操作,可用通過設置代理的方式(delegate)來監聽UIScrollView的整個滾動過程,當UIScrollView發生一系列的滾動操作時, 會自動通知它的代理(delegate)對象,然后通過代理來監聽UIScrollView的滾動過程。
UIScrollView將delegate需 要實現的方法都定義在UIScrollViewDelegate協議中,因此UIScrollView的delegate必須遵守 UIScrollViewDelegate協議,然后實現協議中相應的方法,就可以監聽UIScrollView的滾動過程
// 用戶開始拖拽時調用 - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView;// 滾動到某個位置時調用 - (void)scrollViewDidScroll:(UIScrollView *)scrollView;// 用戶結束拖拽時調用 - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;內容縮放
UIScrollView不僅能滾動顯示大量內容,還能對其內容進行縮放處理
當在UIScrollView身上使用捏合手勢時,UIScrollView會調用代理(delegate)的viewForZoomingInScrollView方法,這個方法返回的控件就是需要進行縮放的控件,縮放涉及的屬性和方法
/****屬性****/ //縮小的對小比例 @property(nonatomic) CGFloat minimumZoomScale;//放大的最大比例 @property(nonatomic) CGFloat maximumZoomScale; /****方法****/ //縮放時調用 - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView;//開始縮放的時候調用 - (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view//正在縮放的時候調用 - (void)scrollViewDidZoom:(UIScrollView *)scrollViewUIScrollView無法滾動的解決辦法
如果UIScrollView無法滾動,可能是以下原因:
5.1 沒有設置contentSize屬性
5.2 設置屬性scrollEnabled = NO
5.3 沒有接收到觸摸事件(userInteractionEnabled = NO)
5.4 取消autolayout功能,要想scrollView滾動,必須取消autolayout
?
?
#import "ViewController.h"@interface ViewController ()<UIScrollViewDelegate> /***UIScrollView*/ @property(nonatomic,strong)UIScrollView *scrollView;/*** UIImageView*/ @property(nonatomic,strong)UIImageView *imageView; @end@implementation ViewController - (void)viewDidLoad {//2.設置 UIImageView UIImage *image = [UIImage imageNamed:@"scroll.jpg"];self.imageView.image = image;//2.1 設置圖片范圍CGFloat imageH = image.size.height;CGFloat imageW = image.size.width;CGFloat imageX = 0;CGFloat imageY = 0;self.imageView.frame = CGRectMake(imageX, imageY, imageW, imageH);//3 設置UIScrollView 屬性//3.2 設置UIScrollView內容的尺寸,滾動范圍self.scrollView.contentSize=CGSizeMake(imageW, imageH);//3.2 設置UIScrollView的4周增加額外的滾動區域CGFloat distance = 100.0f;self.scrollView.contentInset = UIEdgeInsetsMake(distance, distance, distance, distance);//3.3 設置彈簧效果self.scrollView.bounces = YES;//3.4 設置滾動不顯示self.scrollView.showsHorizontalScrollIndicator=NO;self.scrollView.showsVerticalScrollIndicator=NO;//4 UIImageView 添加到 UIScrollView 中 [self.scrollView addSubview:self.imageView];//5 UIScrollView [self.view addSubview:self.scrollView];//6 設置代理self.scrollView.delegate = self;//7 縮放self.scrollView.minimumZoomScale=0.2f;self.scrollView.maximumZoomScale=2.0f;}#pragma mark 代理方法 // 用戶開始拖拽時調用 - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {NSLog(@"開始拖拽"); }// 滾動到某個位置時調用 - (void)scrollViewDidScroll:(UIScrollView *)scrollView {NSLog(@"拖拽中"); }// 用戶結束拖拽時調用 - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {NSLog(@"結束拖拽"); }#pragma mark 縮放 /*** 縮放結束時調用** @param scrollView <#scrollView description#>** @return <#return value description#>*/ - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {NSLog(@"開始縮放");return self.imageView; }/*** 縮放過程中調用** @param scrollView <#scrollView description#>*/ - (void)scrollViewDidZoom:(UIScrollView *)scrollView {NSLog(@"正在縮放"); }/*** 縮放結束時調用** @param scrollView <#scrollView description#>* @param view <#view description#>* @param scale <#scale description#>*/ - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale {NSLog(@"縮放結束"); }#pragma mark 屬性get方法- (UIScrollView *)scrollView {if (!_scrollView) {_scrollView = [[UIScrollView alloc] initWithFrame:self.view.frame];}return _scrollView; }- (UIImageView *)imageView {if (!_imageView) {_imageView = [[UIImageView alloc] init];}return _imageView; }@end===========================================
contentsize是內容的寬和高,contentsize.width是內容的寬度,contentsize.heght是高度,contentsize是UIScrollView的一個屬性,它是一個CGSize,是由核心圖形所定義的架構,那定義了你可以滾軸內容的寬度和高度,你也可以添加可以上下滾動的額外區域。第一種方法是你可以通過添加內容的大小來完成。另外一個比較動態的選擇是UIScrollView的另一個屬性contentInset,contentInset增加你在contentsize中指定的內容能夠滾動的上下左右區域數量contentInset.top以及contentInset.buttom分別表示上面和下面的距離。
???????????在滾軸視圖中,有一個叫做ContentOffset的屬性跟蹤UIScrollView的具體位置,你能夠自己獲取和設置它,ContentOffset是你當前可視內容在滾軸視圖邊界的左上角那個點。如圖:
???????????可以看出,ContentOffset內容中的那個點不是從contentInset的左上角開始的,而是內容的左上角,此時的ContentOffset是正值,但有時也是負值,如下圖所示:
?
?
?
//使用一個ScrollView //創建一個UIScrollView CGRectframe = CGRectMake( 0, 0, 200, 200); scrollView= [[UIScrollView alloc] initWithFrame: frame];//添加子視圖(框架可以超過scroll view的邊界) frame= CGRectMake( 0, 0, 500, 500); myImageView= [[UIImageView alloc] initWithFrame: frame]; [scrollViewaddSubview:myImageView];//設置內容尺寸 scrollView.contentSize= CGSize(500,500);擴展Scroll View?的行為
??????應用程序通常需要知道有關的滾圖的事件
??????????? scrolloffset改變的時候
???????????拖動開始和結束
????????????減速的開始和結束
通過子類化擴展Scroll View?的行為
????????創建一個子類
????????重寫一些功能并改變行為
????????關于這種方式的爭議
| ? | ? |
?
?
轉載于:https://www.cnblogs.com/allanliu/p/4532674.html
總結
以上是生活随笔為你收集整理的ios UIScrollView 基础属性的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Inside NT Boot
- 下一篇: 《你的灯亮着吗》 读书笔记三