【重新整理】關(guān)于Objective-C中UIScrollView的使用總結(jié)

前言:由于之前很早寫的關(guān)于【iOS 關(guān)于UIScrollView的幾點(diǎn)總結(jié)】,是從自己的markdown筆記直接拷貝過(guò)來(lái)后也沒(méi)有整理,所以在閱讀上顯得有點(diǎn)亂, 今天花時(shí)間重新整理排版了下,方便閱讀。還請(qǐng)見(jiàn)諒這么久才重新整理。

1、什么是 UIScrollView ?
  • 當(dāng)手機(jī)屏幕需要展示的內(nèi)容較多超出一個(gè)屏幕時(shí),用戶可以通過(guò)滾動(dòng)手勢(shì)來(lái)查看屏幕以外的內(nèi)容。
  • 普通的 UIView 不具備滾動(dòng)的功能,UIScrollView 是一個(gè)能夠滾動(dòng)的視圖控件,可以用來(lái)展示大量的內(nèi)容,并且可以通過(guò)滾動(dòng)查看所有的內(nèi)容。

2、UIScrollView 的常見(jiàn)屬性
  • UIScrollView 滾動(dòng)的位置
  • 內(nèi)容左上角與 ScrollView 左上角的間距值
@property (nonatomic) CGPoint contentOffset;
image
  • UIScrollView 內(nèi)容的尺寸, 滾動(dòng)范圍
@property (nonatomic) CGSize contentSize;
  • UIScrollView 的4周增加額外的滾動(dòng)區(qū)域,一般用來(lái)避免 ScrollView 的內(nèi)容被其它控件擋住
@property (nonatomic) UIEdgeInsets contentInset;
3、UIScrollView 各尺寸
image

4、UIScrollView 的其他屬性
  • 回彈效果
@property (nonatomic) BOOL bounces;

// 取消回彈效果
self.scrollView.bounces = NO;
  • 是否能滾動(dòng)
@property (nonatomic, getter = isScrollEnabled) BOOL scrollEnabled;
  • 是否顯示水平滾動(dòng)條
@property (nonatomic) BOOL showsHorizontalScrollIndicator;
  • 是否顯示垂直滾動(dòng)條
@property (nonatomic) BOOL showsVerticalScrollIndicator;

5、 UIScrollView 的基本使用
  • 設(shè)置 UIScrollView的contentSize 屬性,告訴 UIScrollView 所有內(nèi)容的尺寸,也就是告訴它滾動(dòng)的范圍

  • UIScrollView 使用步驟

    • 創(chuàng)建 UIScrollView;
    • 將需要展示的內(nèi)容添加到 UIScrollView 中;
    • 設(shè)置 UIScrollView 的滾動(dòng)范圍(contentSize)。
  • 注意:如果想讓 UIScrollView 進(jìn)行滾動(dòng),必須設(shè)置可以滾動(dòng)的范圍,必須設(shè)置可以滾動(dòng)的范圍

  • 一個(gè)控件沒(méi)有設(shè)置 frame ,默認(rèn) x/y 都是 0
6、ScrollView 不能滾動(dòng)的幾種情況
  • 沒(méi)有設(shè)置 contentSize

    • scrollEnabled 屬性 = NO ; // 代表控件不可用

    • userInteractionEnabled 屬性 = NO; // 代表控件不能和用戶交互

image
7、如何去掉滾動(dòng)條
self.scrollView.showsHorizontalScrollIndicator = NO;
self.scrollView.showsVerticalScrollIndicator = NO;
  • 注意:滾動(dòng)條也是 scrollValue 的子控件的一部分

    • 滾動(dòng)條可能在子控件的前面,也可能在子控件的后面
  • 正是因?yàn)檫@個(gè)原因,在開(kāi)發(fā)中不推薦使用 subviews 獲取子控件的方式

  • 當(dāng)沒(méi)有設(shè)置 contentSize 情況下,滾動(dòng)條在其它子控件的前面打印,當(dāng)設(shè)置了contentSize 情況下,滾動(dòng)條在其它子控件后面打印,這說(shuō)明了滾動(dòng)條的位置是不確定的。
image
  • 設(shè)置滾動(dòng)條的樣式
// default is UIScrollViewIndicatorStyleDefault
@property (nonatomic) UIScrollViewIndicatorStyle  indicatorStyle;                
  • 默認(rèn)情況下UIScrollView有一個(gè)回彈效果
    • 只要設(shè)置了contentSize就有回彈效果
// 回彈效果
// default YES. if YES, bounces past edge of content and back again
@property (nonatomic) BOOL bounces;                        
  • 默認(rèn)如果不設(shè)置 contentSize,scrollView是沒(méi)有回彈效果的,可是如果設(shè)置了self.scrollView.alwaysbounceVertical = YES & self.scrollView.alwaysBounceHorizontal = YES的情況下,水平和垂直方向就都有了回彈效果

    • 一般應(yīng)用于下拉刷新功能
image
  • 設(shè)置邊距
  • contentInset(額外增加的邊距)

@property(nonatomic)        UIEdgeInsets                contentInset;                  // default UIEdgeInsetsZero. add additional scroll area around content

  • 設(shè)置內(nèi)容偏移位

    • contentOffset (移動(dòng)的位置是一個(gè)臨時(shí)的位置,只要輕輕拖拽一下就會(huì)回到默認(rèn)的位置)
  • 計(jì)算公式:永遠(yuǎn)都是 控件的左上角 - 內(nèi)容的左上角 = 規(guī)定的值
 // animate at constant velocity to new offset
- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated; 

8、UIScrollView代理
  1. 如何監(jiān)聽(tīng)一個(gè)控件的變化/狀態(tài)
  • 首先需要查看該控件的頭文件,看它繼承于誰(shuí)
  • 如果繼承于UIControl,那么就可以通過(guò)addTarget來(lái)監(jiān)聽(tīng)
  • 如果繼承于UIView,那么就必須通過(guò)代理來(lái)監(jiān)聽(tīng)
  1. 代理作用:
  • 當(dāng) A 對(duì)象想監(jiān)聽(tīng) B 對(duì)象的變化,那么可以讓 A 成為 B 的代理
  • 當(dāng) B 對(duì)象發(fā)生一些變化想通知 A對(duì)象,那么可以讓 A 成為 B 的代理
  • self 寫在對(duì)象方法中就是當(dāng)前對(duì)象的實(shí)例對(duì)象
  1. 代理協(xié)議的規(guī)律:
  • 定義代理都使用 id ,這樣以后就任意對(duì)象都能成為代理(學(xué)官方)
  • 以控件的類名開(kāi)頭,后面加上 delegate
  • 代理協(xié)議可以寫在 interface() 后面,也可以寫在類擴(kuò)展后面,都是可以的
  1. 代理協(xié)議中的方法名的規(guī)律:
  • 一般以控件名稱去掉類前綴開(kāi)頭
  1. 代理協(xié)議中的方法參數(shù)的規(guī)律:
  • 誰(shuí)觸發(fā)事件,就將誰(shuí)傳遞進(jìn)來(lái)
  1. 如何監(jiān)聽(tīng) UIScrollView 的變化
  • 成為UIScrollView的代理
  • 遵守UIScrollView的協(xié)議
  • 實(shí)現(xiàn)UIScrollView協(xié)議中的方法
  1. 只要成為了 UIScrollView 的代理,遵守代理協(xié)議,實(shí)現(xiàn)協(xié)議中的方法,當(dāng)UIScrollView放生一些變化的時(shí)候,系統(tǒng)就會(huì)自動(dòng)調(diào)用這些代理方法
  • scrollViewDidScroll: 方法只要 UIScrollView 滾動(dòng)了,系統(tǒng)就會(huì)自動(dòng)調(diào)用
// 只要UIScrollView滾動(dòng)就會(huì)調(diào)用
// 系統(tǒng)會(huì)自動(dòng)調(diào)用這些方法
- (void)scrollViewDidScroll:(UIScrollView *)scrollView; // any offset changes

// 只要用戶準(zhǔn)備開(kāi)始拖拽就會(huì)調(diào)用
// called on start of dragging (may require some time and or distance to move)
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView;

// 用戶停止拖拽(已經(jīng)松手)
// 但是并不意味著UIScrollView已經(jīng)停止?jié)L動(dòng)了,每次調(diào)用此方法時(shí),系統(tǒng)都會(huì)傳入一個(gè)當(dāng)前是否有慣性的參數(shù)(decelerate)
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;

// UIScrollView停止減速
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;      // called when scroll view grinds to a halt
  1. 注意:
  • 如果想在 UIScrollView 停止?jié)L動(dòng)之后做一些操作,有以下兩種情況:

    • 沒(méi)有慣性:只會(huì)調(diào)用停止拖拽的方法,不會(huì)調(diào)用停止減速的方法
    • 有慣性:既會(huì)調(diào)用停止拖拽的方法,也會(huì)調(diào)用停止減速的方法
  • 所以:以后要判斷UIScrollView是否停止?jié)L動(dòng),需要同時(shí)重寫兩個(gè)方法:

    • scrollViewDidEndDragging
    • scrollViewDidEndDecelerating
// 在開(kāi)發(fā)中如果需要監(jiān)聽(tīng)scrollView滾動(dòng)是否停止可以這樣寫
- (void)scrollViewDidEndDragging:(nonnull UISrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (decelerate == NO) {
  [self scrollViewDidEndDecelerating:scrolView];
} else {

}
}

- (void)scrollViewDidEndDecelerating:(nonnull UIScrollView *)scrollView
{
  // 在這里面寫scrollView停止時(shí)需要做的事情
  NSLog(@"UIScrollView停止?jié)L動(dòng)了");
}
  1. 為什么代理要用 weak
  • 任何對(duì)象都能成為代理,只要兩者之間遵守了代理協(xié)議即可
  • 原因:為了防止循環(huán)引用
  • 控制器-強(qiáng)引用 -> 控制器的 View-強(qiáng)引用 -> subViews數(shù)組-強(qiáng)引用 -> UIScrollView-弱引用 -> 控制器
  • 如果只有一個(gè)控制器的情況,程序一啟動(dòng)就創(chuàng)建的這個(gè)控制器是不會(huì)被釋放的(如果它被釋放,它所執(zhí)行的邏輯肯定不能被執(zhí)行 )
  • 只要數(shù)組中保存了對(duì)象,這個(gè)數(shù)組就會(huì)用強(qiáng)指針指向了這個(gè)對(duì)象
  • strong (用于對(duì)象, 強(qiáng)指針, 強(qiáng)引用)
  • weak(用于對(duì)象, 一般應(yīng)用于控件/代理)
  • copy(用于對(duì)象, 字符串, 主要為了防止外界修改內(nèi)部的屬性的值)
  • assign(用于基本數(shù)據(jù)類型,int/float/double...)
image

9、UIScrollView 縮放
  1. 要想縮放,除了告訴 UIScrollView 要縮放哪一個(gè)控件以外,還要告訴UIScrollView 最小能縮多小,最大能放多大
  • 因?yàn)樗械淖涌丶际俏覀兲砑舆M(jìn)去的,所以要縮放哪一個(gè)我們最清楚
  • 只要讓控制器成為 UIScrollView 的代理,當(dāng) UIScrollView 不清楚要縮放哪一個(gè)控件的時(shí)候, UIScrollView 就會(huì)調(diào)用它的代理方法,問(wèn)問(wèn)代理到底要縮放哪一個(gè)
self.sc.maximumZoomScale = 2.0;
self.sc.minimumZoomScale = 0.5;
  1. 縮放圖片分為兩步
  • 成為代理,通過(guò)代理方法告訴 UIScrollView 要縮放哪一個(gè)子控件
  • 設(shè)置子控件和最小的縮放比
  1. 想要縮放,必須明確告訴 UIScrollView 要縮放哪一個(gè)控件,因?yàn)?UIScrollView中可能有很多子控件
// 代理方法
// 大部分代理方法是由控件名開(kāi)頭,小部分不是
// 在此方法中告訴UIScrollView要縮放哪一個(gè)控件
- (UIView *)viewForZoomingInScrollView:(nonnull UISCrollView *)scrollView {
  return 需要縮放的圖片
}

// 縮放的過(guò)程中調(diào)用
- (void)scrlooViewDidZoom:(nonnull UIScrollView *)scrolView {
}

// 縮放結(jié)束時(shí)調(diào)用
- (void)scrollViewDidEndZooming:(nonnull UIScrollView *)scrollView withView:(nullable UIView *)view atScale:(CGFloat)scale {
}

10、UIScrollView
  1. 一個(gè)控件如果沒(méi)有設(shè)置 frame ,默認(rèn) x/y就是 0
  2. 如果想讓 UIScrollView 進(jìn)行滾動(dòng),必須設(shè)置可以滾動(dòng)的范圍
  • 將需要展示的內(nèi)容添加到 UIScrollView
  • 設(shè)置 UIScrollViewcontentSize 屬性,設(shè)置滾動(dòng)范圍
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width + 100, self.scrollView.frame.size.height + 100);
  1. 注意:scrollView不能滾動(dòng)的幾種情況
  • 沒(méi)有設(shè)置contentSize
  • scrollEnabled 屬性 = NO (代表控件是否可用)
  • userINteractionEnabled屬性 = NO (代表控件不能和用戶交互,不能響應(yīng)用戶操作)

11、UIScrollView 使用步驟
  1. 創(chuàng)建 UIScrollView
  2. 將需要展示內(nèi)容添加到 UISCrollView
  3. 設(shè)置 UISCrollView 的滾動(dòng)范圍(contentSize)
12、UIScrollView 圖片輪播器
  1. pagingEnabled 實(shí)現(xiàn)分頁(yè)的本質(zhì),是按照 UIScrollView 的寬度或者高度來(lái)分頁(yè)的.
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • - 什么是UISCrollView + 當(dāng)手機(jī)屏幕需要展示的內(nèi)容較多超出一個(gè)屏幕時(shí),用戶可以通過(guò)滾動(dòng)手勢(shì)來(lái)查看屏幕...
    Alan張洋閱讀 22,224評(píng)論 2 19
  • 什么是UIScrollView 當(dāng)手機(jī)屏幕需要展示的內(nèi)容較多超出一個(gè)屏幕時(shí),用戶可以通過(guò)滾動(dòng)手勢(shì)來(lái)查看屏幕以外的內(nèi)...
    無(wú)盡思緒閱讀 687評(píng)論 0 3
  • 1、通過(guò)CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫(kù)組件 SD...
    陽(yáng)明AI閱讀 16,171評(píng)論 3 119
  • 清晨,到處都是淡淡的白霧,不久,當(dāng)白霧散盡時(shí),春天的溫暖的陽(yáng)光早已灑滿大地。空氣里的縷縷寒氣已越來(lái)越淡,淡得讓人快...
    ZJGSLTY閱讀 572評(píng)論 0 0
  • 弟弟今天下午4點(diǎn)坐車從北京出發(fā),凌晨就會(huì)回來(lái)了,迎接周一的訂婚儀式。每次他從北京回來(lái),都是我或者老公去接他...
    其樂(lè)媽咪閱讀 160評(píng)論 0 1

友情鏈接更多精彩內(nèi)容