iOSiOS接下来要研究的知识点

iOS开发:使用KVO实现导航条渐变效果

2018-04-11  本文已影响373人  Jason_hzb

序言

在iOS开发中,苹果提供了许多机制给我们进行回调。KVO(key-value-observing)是一种十分有趣的回调机制,在某个对象注册监听者后,在被监听的对象发生改变时,对象会发送一个通知给监听者,以便监听者执行回调操作。最常见的KVO运用是监听scrollView的contentOffset属性,来完成用户滚动时动态改变某些控件的属性实现效果,包括渐变导航栏、下拉刷新控件等效果。

123.gif

使用

KVO的使用非常简单,使用KVO的要求是对象必须能支持kvc机制——所有NSObject的子类都支持这个机制。拿上面的渐变导航栏做,我们为tableView添加了一个监听者controller,在我们滑动列表的时候,会计算当前列表的滚动偏移量,然后改变导航栏的背景色透明度。

//添加监听者
 [self.tableView addObserver: self forKeyPath: @"contentOffset" options: NSKeyValueObservingOptionNew context: nil];

/**
 *  监听属性值发生改变时回调
 */
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    CGFloat offset = self.tableView.contentOffset.y;
    CGFloat delta = offset / kNavBarH + 1.f;
    delta = MAX(0, delta);
    [self bgView].alpha = MIN(1, delta);
}

//移除观察者
- (void)dealloc {
    [self.tableView removeObserver:self forKeyPath:@"contentOffset"];
}

//懒加载实现背景View
- (UIView*)bgView {
    if (_bgView == nil) {
        _bgView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, WIDTH, kNavBarH)];
        _bgView.backgroundColor = KNavBarColor;
        [self.navigationController.navigationBar setValue:_bgView forKey:@"backgroundView"];
    }
    return _bgView;
}

示例代码

//
//  KVOUITableViewVC.h
//  KVC-KVO
//
//  Created by Jason on 2018/4/11.
//  Copyright © 2018年 hzb. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface KVOUITableViewVC : UIViewController

@end
//
//  KVOUITableViewVC.m
//  KVC-KVO
//
//  Created by Jason on 2018/4/11.
//  Copyright © 2018年 hzb. All rights reserved.
//

#import "KVOUITableViewVC.h"

@interface KVOUITableViewVC ()<UITableViewDelegate,UITableViewDataSource>

@property (nonatomic,strong) UITableView *tableView;
@property (nonatomic,strong) UIView *bgView;

@end

@implementation KVOUITableViewVC

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, kNavBarH, WIDTH, HEIGHT) style:UITableViewStylePlain];
    self.tableView.tableFooterView = [[UIView alloc] init]; //不显示没内容的cell
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    [self.view addSubview:self.tableView];
    
    //添加监听者
    [self.tableView addObserver: self forKeyPath: @"contentOffset" options: NSKeyValueObservingOptionNew context: nil];
}

/**
 *  监听属性值发生改变时回调
 */
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    CGFloat offset = self.tableView.contentOffset.y;
    CGFloat delta = offset / kNavBarH + 1.f;
    delta = MAX(0, delta);
    [self bgView].alpha = MIN(1, delta);
}

//移除观察者
- (void)dealloc {
    [self.tableView removeObserver:self forKeyPath:@"contentOffset"];
}

//懒加载实现背景View
- (UIView*)bgView {
    if (_bgView == nil) {
        _bgView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, WIDTH, kNavBarH)];
        _bgView.backgroundColor = KNavBarColor;
        [self.navigationController.navigationBar setValue:_bgView forKey:@"backgroundView"];
    }
    return _bgView;
}

#pragma mark - UITableViewDelegate、UITableViewDataSource

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 100;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *ID = @"cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }
    
    cell.textLabel.text = [NSString stringWithFormat:@"第%ld行",(long)indexPath.row];
    
    return cell;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

源码地址:https://github.com/hanzhanbing/KVC-KVO

上一篇下一篇

猜你喜欢

热点阅读