zoukankan      html  css  js  c++  java
  • 内外分离接口依赖及UIScrollView知识点

    1:Class Extension 还能巧妙的解决一个接口暴露问题

    有些属性或者方法对外可以提供,有些只针对内部的类进行调用;

    // Sark.framework/Sark.h
    @interface Sark : NSObject
    @property (nonatomic, copy) NSString *name;
    @property (nonatomic, copy) NSString *creditCardPassword; // secret!
    @end
    
    // Sark.framework/PrivateSarkWife.h
    @interface PrivateSarkWife : NSObject
    - (void)robAllMoneyFromCreditCardOfSark:(Sark *)sark; // needs password!
    @end

    假设 Sark.h 是 Sark.framework 唯一暴露的 Header,而 framework 中的一个私有类需要获取这个公共类的某个属性(或方法)该怎么办?PrivateSarkWife为Sark.framework内部一个类;上面的 creditCardPassword 属性需要一个对外不可见而对内可见的地方声明,这时候可以利用 Class Extension:

    // Sark.h
    @interface Sark : NSObject
    @property (nonatomic, copy) NSString *name;
    @end
    
    // Sark+Internal.h <--- new
    @interface Sark ()
    @property (nonatomic, copy) NSString *creditCardPassword;
    @end
    
    // Sark.m
    #import "Sark.h"
    #import "Sark+Internal.h" // <--- new

    将对公业务和对私业务用 Class Extension 的形式拆到两个 Header 中,在Sark.m里把两个头文件都进行引用,CreditCardPassword被定义在Sark+Internal.h的头文件里面,这样私有类对私有属性的依赖就被成功隔离开了:

    // PrivateSarkWife.m
    #import "PrivateSarkWife.h"
    #import "Sark+Internal.h" // <--- 私有依赖
    
    @implementation PrivateSarkWife
    - (void)robAllMoneyFromCreditCardOfSark:(Sark *)sark {
        NSString *password = sark.creditCardPassword; // oh yeah!
    }
    @end

    2:UIScrollView知识点

    - (void)viewDidLoad
    {
        [super viewDidLoad];
         
        scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
        scrollView.backgroundColor = [UIColor redColor];
        // 是否支持滑动最顶端
    //    scrollView.scrollsToTop = NO;
        scrollView.delegate = self;
        // 设置内容大小
        scrollView.contentSize = CGSizeMake(320, 460*10);
        // 是否反弹
    //    scrollView.bounces = NO;
        // 是否分页
    //    scrollView.pagingEnabled = YES;
        // 是否滚动
    //    scrollView.scrollEnabled = NO;
    //    scrollView.showsHorizontalScrollIndicator = NO;
        // 设置indicator风格
    //    scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
        // 设置内容的边缘和Indicators边缘
    //    scrollView.contentInset = UIEdgeInsetsMake(0, 50, 50, 0);
    //    scrollView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 50, 0, 0);
        // 提示用户,Indicators flash
        [scrollView flashScrollIndicators];
        // 是否同时运动,lock
        scrollView.directionalLockEnabled = YES;
        [self.view addSubview:scrollView];
         
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 200, 320, 40)];
        label.backgroundColor = [UIColor yellowColor];
        label.text = @"学习scrolleview";
        [scrollView addSubview:label];
        [label release];
    }
     
    #pragma mark - 
    /*
    // 返回一个放大或者缩小的视图
    - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
    {
         
    }
    // 开始放大或者缩小
    - (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:
    (UIView *)view
    {
         
    }
     
    // 缩放结束时
    - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
    {
         
    }
      
    // 视图已经放大或缩小
    - (void)scrollViewDidZoom:(UIScrollView *)scrollView
    {
    NSLog(@"scrollViewDidScrollToTop");
    }
     */
     
    // 是否支持滑动至顶部
    - (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView
    {
        return YES;
    }
     
    // 滑动到顶部时调用该方法
    - (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView
    {
        NSLog(@"scrollViewDidScrollToTop");
    }
     
    // scrollView 已经滑动
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
        NSLog(@"scrollViewDidScroll");
    }
     
    // scrollView 开始拖动
    - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
    {
        NSLog(@"scrollViewWillBeginDragging");
    }
     
    // scrollView 结束拖动
    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
    {
        NSLog(@"scrollViewDidEndDragging");
    }
     
    // scrollView 开始减速(以下两个方法注意与以上两个方法加以区别)
    - (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
    {
        NSLog(@"scrollViewWillBeginDecelerating");
    }
     
    // scrollview 减速停止
    - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
    {
       NSLog(@"scrollViewDidEndDecelerating"); 
    }

     3:仿网易滚动菜单及内容视图滚动效果

    #import "NewsViewController.h"
    
    
    #import "VideoViewController.h"
    #import "ReaderViewController.h"
    #import "ScienceViewController.h"
    #import "SocietyViewController.h"
    #import "HotViewController.h"
    #import "TopLineViewController.h"
    
    #import "TitleButton.h"
    
    #define ScreenW  [UIScreen mainScreen].bounds.size.width
    #define ScreenH  [UIScreen mainScreen].bounds.size.height
    
    
    
    @interface NewsViewController ()<UIScrollViewDelegate>
    
    @property (nonatomic, strong) UIButton *selButton;
    
    
    @property (nonatomic, strong) NSMutableArray *titleBtns;
    
    // 标题滚动view
    @property (weak, nonatomic) IBOutlet UIScrollView *titileScrollView;
    
    // 内容滚动view
    @property (weak, nonatomic) IBOutlet UIScrollView *contentView;
    
    @end
    
    @implementation NewsViewController
    
    - (NSMutableArray *)titleBtns
    {
        if (_titleBtns == nil) {
            _titleBtns = [NSMutableArray array];
        }
        return _titleBtns;
    }
    
    // 头条,热点,视频,社会,订阅,科技(science)
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        
        
        // 添加所有子控制器
        [self setUpChildViewController];
        
        // 设置标题
        [self setUpTitle];
        
        // iOS7之后,导航控制器下所有ScrollView都会添加额外滚动区域
        self.automaticallyAdjustsScrollViewInsets = NO;
        
        
        // 初始化scrollView
        [self setUpScrollView];
        
    }
    
    - (void)setUpScrollView
    {
        self.titileScrollView.showsHorizontalScrollIndicator = NO;
        
        self.contentView.contentSize = CGSizeMake(self.childViewControllers.count * [UIScreen mainScreen].bounds.size.width, 0);
        
        self.contentView.showsHorizontalScrollIndicator = NO;
        self.contentView.pagingEnabled = YES;
        self.contentView.bounces = NO;
        
        self.contentView.delegate = self;
    }
    
    
    - (void)setUpChildViewController
    {
        
        TopLineViewController *topLineVc = [[TopLineViewController alloc] init];
        topLineVc.title = @"头条";
        [self addChildViewController:topLineVc];
        
        HotViewController *hotVc = [[HotViewController alloc] init];
        hotVc.title = @"热点";
        [self addChildViewController:hotVc];
        
        VideoViewController *videoVc = [[VideoViewController alloc] init];
        videoVc.title = @"视频";
        [self addChildViewController:videoVc];
        
        SocietyViewController *societyVc = [[SocietyViewController alloc] init];
        societyVc.title = @"社会";
        [self addChildViewController:societyVc];
        
        ReaderViewController *readerVc = [[ReaderViewController alloc] init];
        readerVc.title = @"订阅";
        [self addChildViewController:readerVc];
        
        ScienceViewController *scienceVc = [[ScienceViewController alloc] init];
        scienceVc.title = @"科技";
        [self addChildViewController:scienceVc];
    }
    
    
    // 设置标题
    - (void)setUpTitle
    {
        NSUInteger count = self.childViewControllers.count;
        
        CGFloat btnX = 0;
        CGFloat btnY = 0;
        CGFloat btnW = 100;
        CGFloat btnH = 44;
        
        for (NSUInteger i = 0; i < count; i++) {
            btnX = i * btnW;
            UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
            btn.tag = i;
            [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
            UIViewController *vc = self.childViewControllers[i];
            [btn setTitle:vc.title  forState:UIControlStateNormal];
            [btn setTitleColor:[UIColor redColor] forState:UIControlStateSelected];
            btn.frame = CGRectMake(btnX, btnY, btnW, btnH);
            [btn addTarget:self action:@selector(titleClick:) forControlEvents:UIControlEventTouchUpInside];
            
            [self.titileScrollView addSubview:btn];
            
            [self.titleBtns addObject:btn];
            // 默认选中第一个
            if (i == 0) {
                [self titleClick:btn];
                
            }
        }
        
        self.titileScrollView.contentSize = CGSizeMake(btnW * count, 0);
        
    }
    
    // 点击标题按钮
    - (void)titleClick:(UIButton *)btn
    {
    
        
        // 0.设置标题按钮居中
        [self setUpTitleBtnMiddle:btn];
        
        // 1.滚动到对应的界面
        CGFloat offsetX = btn.tag * ScreenW;
        
        self.contentView.contentOffset = CGPointMake(offsetX, 0);
        
        // 2.添加对应子控制器view到对应的位置
        UIViewController *vc = self.childViewControllers[btn.tag];
        
        vc.view.frame = CGRectMake(offsetX, 0, ScreenW, self.contentView.bounds.size.height);
        
    //    NSLog(@"%@",NSStringFromCGRect(self.contentView.bounds));
        [self.contentView addSubview:vc.view];
        
        // 还原之前标题的形变
        [self setSelectBtn:btn];
        
    }
    
    - (void)setSelectBtn:(UIButton *)btn
    {
        _selButton.transform = CGAffineTransformIdentity;
        [_selButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        _selButton.selected = NO;
        
        btn.transform = CGAffineTransformMakeScale(1.3, 1.3);
        btn.selected = YES;
        
        _selButton = btn;
    
    }
    
    #pragma mark - UIScrollViewDelegate
    // 减速完成的时候
    - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
    {
        // 获取当前的偏移量
        CGFloat offsetX = scrollView.contentOffset.x;
        // 获取页码
        int page = offsetX / scrollView.bounds.size.width;
        
        UIButton *btn = self.titileScrollView.subviews[page];
        
        // 选中按钮
        [self setSelectBtn:btn];
       
        
        // 设置按钮居中
        [self setUpTitleBtnMiddle:btn];
        
        // 添加对应子控制器到界面上
        UIViewController *vc = self.childViewControllers[page];
        
        // 已经加载的view就不需要添加了
        if (vc.isViewLoaded) return;
        
        vc.view.frame = CGRectMake(offsetX , 0, self.contentView.bounds.size.width, self.contentView.bounds.size.height);
        
        [self.contentView addSubview:vc.view];
    }
    
    // 设置标题按钮居中
    - (void)setUpTitleBtnMiddle:(UIButton *)btn
    {
        
        // 计算偏移量
        CGFloat offsetX = btn.center.x - ScreenW * 0.5;
        
        // 左边偏移多了,表示需要往左边看,可视范围往左边,偏移量就减少,最少应该是0
        if (offsetX < 0) offsetX = 0;
        CGFloat maxOffsetX = self.titileScrollView.contentSize.width - ScreenW;
        
        // 右边偏移多了,表示需要往右边看,可视范围往又边,偏移量就增加,最大不超过内容范围 - 屏幕宽度
        if (offsetX > maxOffsetX) offsetX = maxOffsetX;
    
        
        [self.titileScrollView setContentOffset:CGPointMake(offsetX, 0) animated:YES];
        
    }
    
    
    // 监听内容view滚动
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
        CGFloat page = scrollView.contentOffset.x / scrollView.bounds.size.width;
        
        
        NSInteger leftIndex = page;
        
        // 右边缩放比例
        CGFloat rightScale = (page - leftIndex);
        // 左边缩放比例
        CGFloat leftScale = (1 - rightScale);
        
        NSInteger rightIndex = leftIndex + 1;
        
        // 获取左边按钮
        TitleButton *leftBtn = self.titleBtns[leftIndex];
        
        NSInteger count = self.titleBtns.count;
        
        // 获取右边按钮
        TitleButton *rightBtn;
        
        if (rightIndex < count) {
           rightBtn  = self.titleBtns[rightIndex];
        }
        
        
        // 设置尺寸
        CGFloat leftTransform = leftScale * 0.3 + 1; // 1 ~ 1.3
        CGFloat rightTransform = rightScale * 0.3 + 1; // 1 ~ 1.3
        leftBtn.transform = CGAffineTransformMakeScale(leftTransform, leftTransform);
        rightBtn.transform = CGAffineTransformMakeScale(rightTransform, rightTransform);
        
        // 设置颜色
        /*
         RGB 红色: 1 0 0
             黑色: 0 0 0
         */
    
        UIColor *leftColor = [UIColor colorWithRed:leftScale green:0 blue:0 alpha:1];
        UIColor *rightColor = [UIColor colorWithRed:rightScale green:0 blue:0 alpha:1];
        
        [leftBtn setTitleColor:leftColor forState:UIControlStateNormal];
        [rightBtn setTitleColor:rightColor forState:UIControlStateNormal];
        
        
        
    }
    
    
    @end

     效果图如下:

  • 相关阅读:
    docker与虚拟机性能比较
    CAP原则(CAP定理)、BASE理论
    CAP 定理的含义
    JVM监测分析JConsole
    JConsole详解
    jconsole工具使用
    轻松看懂Java字节码
    JVM 虚拟机字节码指令表
    深入理解java虚拟机(六)字节码指令简介
    大话+图说:Java字节码指令——只为让你懂
  • 原文地址:https://www.cnblogs.com/wujy/p/5463180.html
Copyright © 2011-2022 走看看