UIScrollView基本使用:
1.設置可以滾動的范圍 contentSize
self.scrollView.contentSize = XXX.size;
2.設置內容的偏移量 contentOffset
作用1:控制內容滾動的位置 作用2:得知內容滾動的位置 self.scrollView.contentOffset = CGPointMake(0, -100);
3.設置滾動區域四周的滾動范圍 contentInset
self.scrollView.contentInset = UIEdgeInsetsMake(10, 10, 10, 10);
4.指定控件是否只能在一個方向上滾動(默認NO)
self.scrollView.directionalLockEnabled = YES;
5.是否有彈簧效果
self.scrollView.bounces = NO; 不管有沒有設置contentSize,總是有彈簧效果(下拉刷新) self.scrollView.alwaysBounceHorizontal = YES; self.scrollView.alwaysBounceVertical = YES;
6.當值是 YES 會自動滾動到 subview 的邊界(默認NO)
self.scrollView.pagingEnabled = YES;
7.控制控件是否能滾動(默認YES)
self.scrollView.scrollEnabled = NO;
8.點擊狀態欄回到頂部(默認YES)
self.scrollView.scrollsToTop = YES;
9.是否顯示滾動條
水平方向 self.scrollView.showsHorizontalScrollIndicator = NO; 垂直方向 self.scrollView.showsVerticalScrollIndicator = NO;
10.指定滾動條在scrollerView中的位置
self.scrollView.scrollIndicatorInsets=UIEdgeInsetsMake(64.0, 0.0, 44.0, 0.0);
11.設置滾動條樣式
默認:灰色線包圍黑色條
self.scrollView.indicatorStyle = UIScrollViewIndicatorStyleDefault;
12.內邊距
self.scrollView.contentInset = UIEdgeInsetsMake(100, 0, 50, 0);
13.自動調整寬高
self.scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
14.設置子控件不能滾動:
//UIScrollView設置子控件不跟隨自己滾動 -(void)layoutSubviews { [super layoutSubviews]; for (UIView*view in self.subviews) { if ([view isKindOfClass:[UIImageView class]]) { CGRect rect = view.frame; rect.origin.y = self.contentOffset.y; view.frame = rect; } } }
15.手勢沖突
//返回YES,則可以多個手勢一起觸發方法,返回NO則為互斥(比如外層UIScrollView名為mainScroll內嵌的UIScrollView名為subScroll,當我們拖動subScroll時,mainScroll是不會響應手勢的(多個手勢默認是互斥的),當下面這個代理返回YES時,subScroll和mainScroll就能同時響應手勢,同時滾動,這符合我們這里的需求) - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { return YES; }
16.UIScrollView點擊狀態欄返回頂部
在iOS開發中,UIScrollView自帶點擊狀態欄自動返回頂部的效果: BOOL scrollsToTop.
這個手勢只能作用在一個scrollView上,當發現多個時,手勢將會失效。
在實際應用中,我們可能會有多個scrollView,這時,系統默認的點擊狀態欄返回頂部效果就會失效,我們就得自己自定義控件來實現此功能了。
思路:①自定義一個Window②監聽頂部窗口點擊③找到參數View中所有的UIScrollView④讓UIScrollView滾到最前面。
自定義一個Window
#import <UIKit/UIKit.h> NS_ASSUME_NONNULL_BEGIN @interface HKWindow : UIWindow + (void)show; + (void)hide; @end NS_ASSUME_NONNULL_END #import "HKWindow.h" #import "HKTopViewController.h" @implementation HKWindow // 全局對象 static UIWindow *topWindow_; + (void)initialize { topWindow_ = [[UIWindow alloc] init]; topWindow_.frame = [UIApplication sharedApplication].statusBarFrame; topWindow_.windowLevel = UIWindowLevelAlert; topWindow_.backgroundColor = [UIColor clearColor]; HKTopViewController *rootVc = [HKTopViewController sharedInstance]; topWindow_.rootViewController = rootVc; } + (void)show { topWindow_.hidden = NO; } + (void)hide { topWindow_.hidden = YES; } @end
HKTopViewController
#import <UIKit/UIKit.h> NS_ASSUME_NONNULL_BEGIN @interface HKTopViewController : UIViewController + (HKTopViewController *)sharedInstance; @end NS_ASSUME_NONNULL_END #import "HKTopViewController.h" @interface HKTopViewController () @end @implementation HKTopViewController + (HKTopViewController *)sharedInstance { static dispatch_once_t onceToken; static HKTopViewController * _sharedInstance; dispatch_once(&onceToken, ^{ _sharedInstance = [[self alloc] init]; }); return _sharedInstance; } -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { UIWindow *window = [UIApplication sharedApplication].keyWindow; [self searchScrollViewInView:window]; } // 遞歸搜索所有view查找當前位置合適的scrollView - (void)searchScrollViewInView:(UIView *)view { for (UIScrollView *subView in view.subviews) { if ([subView isKindOfClass:[UIScrollView class]] && [self isShowingInKeyWindow:subView]) { //開始進行滾動 CGPoint offset = subView.contentOffset; offset.y = -subView.contentInset.top; [subView setContentOffset:offset animated:YES]; } //尋找子視圖的子視圖 [self searchScrollViewInView:subView]; } } // 根據位置判斷是否合適 - (BOOL)isShowingInKeyWindow:(UIView *)view { UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow; CGRect currentFrame = [keyWindow convertRect:view.frame fromView:view.superview]; CGRect winBounds = keyWindow.bounds; BOOL intersects = CGRectIntersectsRect(currentFrame, winBounds); return !view.isHidden && view.alpha > 0.01 && view.window == keyWindow && intersects; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. } @end
17.ScrollView固定滾動方向
- (void)scrollViewDidScroll:(UIScrollView *)scrollView { CGPoint point = scrollView.contentOffset; // 限制y軸不動 point.y = 0.f;//Y軸不動(不能左右滑動) //point.x = 0.f;//X軸不動(不能上下滑動) scrollView.contentOffset = point; }
17.UIScrollView自動布局
//scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
//UIScrollView做自動布局: 首先確定scrollView滾動范圍 => 如何在stroboard對scrollView確定滾動范圍 => 搞一個專門view去確定scrollView的滾動范圍 => 如何確定:水平 和 垂直方向 => scrollView水平能否滾動: view的寬度 + 左右兩邊間距 才能確定scrollView水平滾動區域 => 垂直 = view的高度 + 上下兩邊間距 UIScrollView底層實現: @interface ViewController ()<UIScrollViewDelegate> @property (nonatomic, weak) UIView *scrollView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // 模仿系統控件 => 怎么去使用 => 滾動scrollView,其實本質滾動內容 => 改bounds => 驗證 // => 手指往上拖動,bounds y++ ,內容才會往上走 UIView *scrollView = [[UIView alloc] initWithFrame:self.view.bounds]; [self.view addSubview:scrollView]; _scrollView = scrollView; // 添加Pan手勢 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)]; [scrollView addGestureRecognizer:pan]; UISwitch *switchView = [[UISwitch alloc] init]; [scrollView addSubview:switchView]; } - (void)pan:(UIPanGestureRecognizer *)pan { // 獲取手指的偏移量 CGPoint transP = [pan translationInView:pan.view]; // 修改bounds CGRect bounds = _scrollView.bounds; bounds.origin.y -= transP.y; _scrollView.bounds = bounds; // 復位 [pan setTranslation:CGPointZero inView:pan.view]; } #pragma mark - UIScrollViewDelegate - (void)scrollViewDidScroll:(UIScrollView *)scrollView{ NSLog(@"%@",NSStringFromCGRect(scrollView.bounds)); NSLog(@"%@",NSStringFromCGPoint(scrollView.contentOffset)); }
18.UIScrollView當方向禁止向上或者向下滑動
//我們有時候可能會需要單方向的禁止滑動,但是官方直接提供的方法只能禁止滑動,在這里我們用UITableView 或者 UIScrollView 的代理方法 - (void)scrollViewDidScroll:(UIScrollView *)scrollView{ //到頂部后不再向上滑動 if (scrollView.contentOffset.y < 0) { [self.tableView setContentOffset:CGPointZero animated:NO]; } //到底部后不再向下滑動 if (scrollView.contentOffset.y + CGRectGetHeight(self.udView.tableView.frame) >scrollView.contentSize.height){ [self.tableView setContentOffset:CGPointMake(selftableView.contentOffset.x,self.tableView.contentSize.height - CGRectGetHeight(self.tableView.frame)) animated:NO]; } }
Swift-版
func scrollViewDidScroll(scrollView: UIScrollView) { // 禁止下拉 if scrollView.contentOffset.y <= 0 { scrollView.contentOffset.y = 0 } // 禁止上拉 if scrollView.contentOffset.y >= scrollView.contentSize.height - scrollView.bounds.size.height { scrollView.contentOffset.y = scrollView.contentSize.height - scrollView.bounds.size.height } }
