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

     

     

     

     

     

     

     

  • 相关阅读:
    UVa 10474
    UVa 1339
    UVa 1368
    UVa 1585
    UVa 1586
    ACM中Java高效输入输出封装
    Ajax中Get请求与Post请求的区别
    AJAX——核心XMLHttpRequest对象
    PHP面向对象编程之深入理解方法重载与方法覆盖(多态)
    PHP类方法重写原则
  • 原文地址:https://www.cnblogs.com/StevenHuSir/p/10040194.html
Copyright © 2011-2022 走看看