zoukankan      html  css  js  c++  java
  • UIScrollView详解

    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
        }
    }

     

     

     

     

     

     

     

  • 相关阅读:
    leetcode 190 Reverse Bits
    vs2010 单文档MFC 通过加载位图文件作为客户区背景
    leetcode 198 House Robber
    记忆化搜索(DP+DFS) URAL 1183 Brackets Sequence
    逆序数2 HDOJ 1394 Minimum Inversion Number
    矩阵连乘积 ZOJ 1276 Optimal Array Multiplication Sequence
    递推DP URAL 1586 Threeprime Numbers
    递推DP URAL 1167 Bicolored Horses
    递推DP URAL 1017 Staircases
    01背包 URAL 1073 Square Country
  • 原文地址:https://www.cnblogs.com/StevenHuSir/p/10040194.html
Copyright © 2011-2022 走看看