UIScrollView、控件悬停、顶部图下拉放大效果、UITouch事件


title : UIScrollView、控件悬停、顶部图下拉放大效果、UITouch事件
category : UI


UIScrollView、控件悬停、顶部图下拉放大效果、UITouch事件

标签(空格分隔): UI


[TOC]

UIScrollView的基本属性

- 超出UIScrollView边框的内容会被自动隐藏
- contentSize
    - 设置scrollView的contentSize属性,告诉UIScrollView所有内容的尺寸,也就是告诉它滚动范围(最多能滚多远)
    - UIScrollView无法滚动的可能原因
        - 没有设置contentSize
        - scrollEnabled = NO;
        - 禁止了触摸事件:userInteractionEnabled = NO
    - 如果想要禁止某个方向的滚动,那么就可以直接设置这个方向的contentSize为0

eg:

// 禁止水平方向上滚动
self.scrollView.contentSize = CGSizeMake(0, 500);
  • contentOffset:(偏移量)
- 记录UIScrollView滚动的位置,也就是内容的左上角和scrollView自身左上角X\Y的差值
    - 对于X\Y值,如果内容往左上方滚动,X\Y都是增加,如果内容往右下方滚动,X\Y都是减少
        

eg:

// 往下移动64
self.scrollView.contentOffset = CGPointMake(0, -64);

OC语法细节:OC不允许直接修改结构体对象的属性成员变量

  • contentInset:内边距
- 这个属性能够在UIScrollView的四周增加额外的滚动区域,一般用来避免scrollView的内容被其他控件挡住(比如不被导航条挡住)

eg:

// 顶部多出64的内边距
self.scrollView.contentInset = UIEdgeInsetsMake(64, 0, 0, 0);

UIScrollView的其他属性


- BOOL bounces
    - 设置UIScrollView是否需要弹簧效果
- BOOL scrollEnabled
    - 设置UIScrollView是否能滚动
- BOOL showHorizontalScrollIndicator
    - 是否显示水平滚动条
- BOOL showsVerticalScrollIndicator
    - 是否显示垂直滚动条 
- BOOL pagingEnabled
    - 是否分页
       

注意

  • iOS7以后,导航控制器会为其中的scrollView的顶部自动添加64的内边距,如果想去掉,可以通过下列属性去掉
  • tabBarController为间隔区域的bottom添加49
  • 取消自动添加额外滚动区域
self.automaticallyAdjustsScrollViewInsets = NO;

UIScrollView的代理方法

  • 使用方法
    • 首先准守协议
    • 设置代理
    • 实现代理方法
  • 注意
    • 如果其他类(A类)成为该类中UIScrollView的代理的话,需要将 A类设成Strong,然后它成为当前类中scrollView的代理
  • 常用代理方法为
/**
 *  滚动的时候调用
 */
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{

}

/**
 *  即将开始拖拽的时候调用
 */
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    
}

/**
 *  结束拖拽的时候调用
 */
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    
}

/**
 *  (减速完毕)停止滚动的时候调用
 */
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    
}
  • scrollView实现内容缩放
// 最大缩放比例
self.scrollView.maximumZoomScale = 2.0;
// 最小缩放比例
self.scrollView.minimumZoomScale = 0.2;

// 同时实现代理方法
// 返回要缩放的内容控件,注意,该内容控件必须是scrollView的子控件
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return self.imageView;
}

// 这个方式是内容缩放的时候调用,通过在该方法中调节内容控件的frame可以使缩放的时候内容控件始终处于scrollView的正中间
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
    
}
  • 其他方法
// 将scrollView中的所有子控件都执行removeFromSuperview方法
[scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

ScrollView内部子控件添加约束的注意点

  • 子控件的尺寸不能通过UIScrollView来计算,可以考虑通过以下方式计算

    • 可以设置尺寸为固定值
    • 可以相对于UIScrollView以外的其他控件来计算尺寸
  • UIScrollView的frame应该通过子控件以外的其他控件来计算

  • UIScrollView的contentSize的尺寸是通过子控件来计算的

    • 根据子控件的尺寸以及子控件与UIScrollView之间的间距

ScrollView的一些特效效果

控件悬停效果

当scrollView往上拖拽到某一个位置的时候,控件(testView)悬停到某一个位置,当scrollView往下拉的时候,该控件(testView)又随着scrollView一起移动

实现思路:

当往上拖拽到一定位置的时候(通过计算偏移量来判断),让该控件(testView)添加到self.view上,并设置该控件(testView)的frame固定到该位置,当scrollView再次往回拖拽到该位置的时候,再让该控件(testView)再添加到scrollView上,成为scrollView的子控件

顶部图片下拉放大效果

当scrollView往下拖拽的时候,让顶部的imageView按比例放大

实现思路:

当scrollView往下拖拽的时候,通过偏移量来修改顶部imageView的transform(缩放的transform)。

eg:


- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGFloat imageH = self.imageView.frame.size.height;
    CGFloat offsetY = scrollView.contentOffset.y;
    // 该判断是实现scrollView内部的子控件悬停效果
    if (offsetY >= imageH) {
        // 将红色控件添加到控制器的view中,设置Y值为0
        CGRect redF = self.redView.frame;
        redF.origin.y = 0;
        self.redView.frame = redF;
        [self.view addSubview:self.redView];
    }else{
        // 将红色控件添加到scrollView中,设置Y值为图片的高度
        CGRect redF = self.redView.frame;
        redF.origin.y = 140;
        self.redView.frame = redF;
        [self.scrollView addSubview:self.redView];
    }
    
    // 实现下拉放大顶部图片效果
    CGFloat scale = 1 - (offsetY / 70);
    scale = (scale >= 1) ? scale : 1;
    self.imageView.transform = CGAffineTransformMakeScale(scale, scale);
}

分页指示器UIPageControl

  • UIPageControl
    • 颜色指示器
      • tintColor: 其他页面的指示颜色
      • currentPageIndicatorTintColor:当前页颜色
      • numberOfPages:总共有多少页

注意 一定不要将UIPageControl放到UIScrollView里,这样的话UIScrollView的内容拖动的时候容易把UIPageControl拖走

  • pageControl.hidesForSinglePage = YES;
    • 当只有一页时自动隐藏pageControl

关于UIScrollView不能响应UITouch事件的解决办法

原因是:UIView的touch事件被UIScrollView捕获了。

解决办法:让UIScrollView将事件传递过去。于是最简单的解决办法就是加一个UIScrollView的category。这样每个用到UIScrollView的地方只要导入这个category就可以直接响应相关的touch事件了。

#import "UIScrollView+UITouch.h"

@implementation UIScrollView (UITouch)

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
  [[self nextResponder] touchesBegan:touches withEvent:event];
  [super touchesBegan:touches withEvent:event];
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
  [[self nextResponder] touchesMoved:touches withEvent:event];
  [super touchesMoved:touches withEvent:event];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
  [[self nextResponder] touchesEnded:touches withEvent:event];
  [super touchesEnded:touches withEvent:event];
}

@end

你可能感兴趣的:(UIScrollView、控件悬停、顶部图下拉放大效果、UITouch事件)