iOS,自定义控件
下拉刷新控件
@property(nonatomic,strong) VRefreshHeadView *vrefresh;
[self vrefresh];
-(VRefreshHeadView *)vrefresh{
__weak typeof(self) weakSelf = self;
if (!_vrefresh) {
_vrefresh=[[VRefreshHeadView alloc] initWithScrollView:weakSelf.tbView beginRefreshBlock:^(VRefreshHeadView *vrefresh) {
NSLog(@"进入刷新回调");
[self performSelector:@selector(endVrefresh) withObject:nil afterDelay:3.0f];
}];
}
return _vrefresh;
}
-(void)endVrefresh{
[_vrefresh endRefresh];
}
//
// VRefreshHeadView.h
// 下拉刷新控件
//
// Created by Vie on 2016/10/10.
// Copyright © 2016年 Vie. All rights reserved.
//
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSUInteger, VRefreshType) {
VRefreshTypeDefault = 0,//默认下拉刷新样式
};
@interface VRefreshHeadView : UIView
typedef void (^beginRefreshBlock) (VRefreshHeadView *vrefresh);//刷新事件回调
@property(nonatomic,assign) NSUInteger type;//刷新视图样式
/**
创建下拉刷新视图
@param scrollView 滚动视图
@param beginRefreshBlock 开始刷新回调
@return 刷新视图对象
*/
-(instancetype)initWithScrollView:(UIScrollView *)scrollView beginRefreshBlock:(beginRefreshBlock)beginRefreshBlock;
//停止刷新
-(void)endRefresh;
@end
//
// VRefreshHeadView.m
// 下拉刷新控件
//
// Created by Vie on 2016/10/10.
// Copyright © 2016年 Vie. All rights reserved.
//
#import "VRefreshHeadView.h"
#define vRefreshHeadViewHeight 40
#define navBarHeight 64 //竖屏导航栏和控制器高度(竖屏导航栏高度44,竖屏状态栏高度为20、打电话或者某些情况为40)
@interface VRefreshHeadView ()
@property (nonatomic,copy) beginRefreshBlock beginRefreshBlock;
@property(nonatomic,weak) UIScrollView *scrollView;
/**
*头部提示语
*/
@property(nonatomic,weak) UILabel *headTipLable;
/**
* 加载提示
*/
@property (nonatomic, weak) UIActivityIndicatorView *indicatorView;
/**
*是否处于刷新状态
*/
@property(nonatomic,assign) BOOL isRefresh;
@end
@implementation VRefreshHeadView
#pragma mark - init方法
-(instancetype)initWithScrollView:(UIScrollView *)scrollView beginRefreshBlock:(beginRefreshBlock)beginRefreshBlock{
self=[super initWithFrame:CGRectMake(0, -vRefreshHeadViewHeight, scrollView.frame.size.width, vRefreshHeadViewHeight)];
if (self) {
_scrollView=scrollView;
_beginRefreshBlock=beginRefreshBlock;
//把当前视图加载到scrollView的UI
[_scrollView addSubview:self];
//设置背景颜色
self.backgroundColor=[UIColor clearColor];
//默认不在刷新状态
self.isRefresh=false;
//注册观察者,监听下拉刷新改变
[_scrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
}
return self;
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
if ([keyPath isEqualToString:@"contentOffset"]) {
if (_scrollView.contentOffset.y<(-navBarHeight-vRefreshHeadViewHeight)&&!self.isRefresh&&_scrollView.dragging) {
[self.indicatorView startAnimating];
self.isRefresh=true;
self.headTipLable.text=@"加载中..";
_scrollView.contentInset = UIEdgeInsetsMake(vRefreshHeadViewHeight+navBarHeight, 0, 0, 0);
if (_beginRefreshBlock) {
_beginRefreshBlock(self);
}
}
}
}
//停止刷新
-(void)endRefresh{
[UIView animateWithDuration:0.3 animations:^{
// _scrollView.contentInset = UIEdgeInsetsZero;
_scrollView.contentInset = UIEdgeInsetsMake(navBarHeight, 0, 0, 0);
} completion:^(BOOL finished) {
[self.indicatorView stopAnimating];
self.isRefresh=false;
_headTipLable.text=@"下拉刷新数据";
}];
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
*/
- (void)drawRect:(CGRect)rect {
// Drawing code
if (_type) {
}else{
//没有指定type用默认视图
[self setDefaultView];
}
}
//默认样式
-(void)setDefaultView{
[self headTipLable];
}
#pragma mark - 懒加载创建控件
- (UIActivityIndicatorView *)indicatorView
{
if (!_indicatorView)
{
UIActivityIndicatorView *act = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(50, 0, 30, self.frame.size.height)];
act.color = [UIColor grayColor];
[self addSubview:act];
_indicatorView = act;
}
return _indicatorView;
}
-(UILabel *)headTipLable{
if (!_headTipLable) {
UILabel *lb = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width,self.frame.size.height)];
lb.textAlignment = NSTextAlignmentCenter;
lb.textColor = [UIColor grayColor];
lb.font = [UIFont systemFontOfSize:13];
lb.text = @"下拉刷新数据";
[self addSubview:lb];
_headTipLable = lb;
}
return _headTipLable;
}
-(void)dealloc{
[_scrollView removeObserver:self forKeyPath:@"contentOffset"];
}
@end
下拉加载更多控件
@property(nonatomic,strong) VLoadMoreFootView *vload;
[self vload];
-(VLoadMoreFootView *)vload{
__weak typeof(self) weakSelf=self;
if (!_vload) {
_vload=[[VLoadMoreFootView alloc] initWithScrollView:weakSelf.tbView beginLoadMoreBlock:^(VLoadMoreFootView *vrefresh) {
NSLog(@"进入上拉加载");
[self performSelector:@selector(endVload) withObject:nil afterDelay:3.0f];
}];
}
return _vload;
}
-(void)endVload{
[_vload endLoadMore];
}
//
// VLoadMoreFootView.h
// 上拉加载更多控件
//
// Created by Vie on 2016/10/17.
// Copyright © 2016年 Vie. All rights reserved.
//
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSUInteger, VLoadMoreType) {
VLoadMoreTypeDefault = 0,//默认上拉加载样式
};
@interface VLoadMoreFootView : UIView
typedef void (^beginLoadMoreBlock) (VLoadMoreFootView *vrefresh);//加载更多事件回调
@property(nonatomic,assign) NSUInteger type;//加载更多视图样式
/**
创建上拉加载新视图
@param scrollView 滚动视图
@param beginLoadMoreBlock 开始加载更多回调
@return 加载视图对象
*/
-(instancetype)initWithScrollView:(UIScrollView *)scrollView beginLoadMoreBlock:(beginLoadMoreBlock)beginLoadMoreBlock;
//停止加载
-(void)endLoadMore;
@end
//
// VLoadMoreFootView.m
// 上拉加载更多控件
//
// Created by Vie on 2016/10/17.
// Copyright © 2016年 Vie. All rights reserved.
//
#import "VLoadMoreFootView.h"
#define vLoadMoreBottomViewHeight 40
#define navBarHeight 64 //竖屏导航栏和控制器高度(竖屏导航栏高度44,竖屏状态栏高度为20、打电话或者某些情况为40)
@interface VLoadMoreFootView()
@property(nonatomic,copy) beginLoadMoreBlock beginLoadMoreBlock;
@property(nonatomic,weak) UIScrollView *scrollView;
/**
*底部提示语
*/
@property(nonatomic,weak) UILabel *bottomTipLable;
/**
*加载提示
*/
@property(nonatomic,weak) UIActivityIndicatorView *indicatorView;
/**
*是否处于加载状态
*/
@property(nonatomic,assign) BOOL isLoad;
@end
@implementation VLoadMoreFootView
#pragma mark - init方法
-(instancetype)initWithScrollView:(UIScrollView *)scrollView beginLoadMoreBlock:(beginLoadMoreBlock)beginLoadMoreBlock{
self=[super initWithFrame:CGRectMake(0, 0, scrollView.frame.size.width, vLoadMoreBottomViewHeight)];
if (self) {
_scrollView=scrollView;
_beginLoadMoreBlock=beginLoadMoreBlock;
//把当前视图加载到scrollView的UI
[_scrollView addSubview:self];
//设置背景颜色
self.backgroundColor=[UIColor clearColor];
//默认不在加载状态
self.isLoad=false;
//注册观察这,监听上拉加载改变
[_scrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
}
return self;
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
if ([keyPath isEqualToString:@"contentOffset"]) {
if (_scrollView.contentOffset.y>(_scrollView.contentSize.height-_scrollView.frame.size.height)&&!self.isLoad&&_scrollView.dragging) {
[self.indicatorView startAnimating];
self.isLoad=true;
self.bottomTipLable.text=@"加载中..";
_scrollView.contentInset = UIEdgeInsetsMake(0, 0, vLoadMoreBottomViewHeight, 0);
if (_beginLoadMoreBlock) {
_beginLoadMoreBlock(self);
}
}
}
}
//停止加载
-(void)endLoadMore{
[UIView animateWithDuration:0.3 animations:^{
// _scrollView.contentInset = UIEdgeInsetsZero;
_scrollView.contentInset = UIEdgeInsetsMake(navBarHeight, 0, 0, 0);
} completion:^(BOOL finished) {
[self.indicatorView stopAnimating];
self.isLoad=false;
_bottomTipLable.text = @"上拉加载更多数据";
}];
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
*/
- (void)drawRect:(CGRect)rect {
// Drawing code
if (_type) {
}else{
//没有指定type用默认视图
[self setDefaultView];
}
}
//默认样式
-(void)setDefaultView{
[self bottomTipLable];
}
-(UILabel *)bottomTipLable{
if (!_bottomTipLable) {
UILabel *lb = [[UILabel alloc] initWithFrame:CGRectMake(0, _scrollView.contentSize.height, self.frame.size.width,self.frame.size.height)];
lb.textAlignment = NSTextAlignmentCenter;
lb.textColor = [UIColor grayColor];
lb.font = [UIFont systemFontOfSize:13];
lb.text = @"上拉加载更多数据";
[self addSubview:lb];
_bottomTipLable = lb;
}
return _bottomTipLable;
}
#pragma mark - 懒加载创建控件
- (UIActivityIndicatorView *)indicatorView
{
if (!_indicatorView)
{
UIActivityIndicatorView *act = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(50, _scrollView.contentSize.height, 30, self.frame.size.height)];
act.color = [UIColor grayColor];
[self addSubview:act];
_indicatorView = act;
}
return _indicatorView;
}
-(void)dealloc{
[_scrollView removeObserver:self forKeyPath:@"contentOffset"];
}
@end
iOS,自定义控件的更多相关文章
- iOS 自定义控件开发(中)
<iOS 自定义控件开发(上)> <iOS 自定义控件开发(中)> 接上篇iOS自定义控件开发之后,我们尝试另外一种. 在Xcode的右边,会看到如下的图 其中,上面有一个:C ...
- iOS 自定义控件开发(上)
工作需要,最近在进行iOS方面的图表工作.找了很多第三方库都无法实现效果,所以决定自己写一个控件. <iOS 自定义控件开发(上)> <iOS 自定义控件开发(中)> #0 目 ...
- iOS自定义控件教程:制作一个可重用的旋钮
当你的APP需要一些新功能时,自定义UI控件会十分有用,尤其是这些自定义控件可以在其他APP里面很好的重用.Colin Eberhart写过一篇很棒的介绍自定义UI控件的教程.这个教程涉及的是一个继承 ...
- 分享一下我封装iOS自定义控件的体会,附上三个好用的控件Demo <时间选择器&多行输入框&日期选择器>
前段时间有小伙伴问到我:"这样的控件该怎么做呢?",我感觉是个比较简单的控件,可能对于入行不久的同志思路没有很清晰吧.趁着最近工作不忙,就来这里分享一下我封装自定义控件的几点体会吧 ...
- 关于iOS自定义控件:在view上实现事件和代理
自定义控件.h #import <UIKit/UIKit.h> #import "PPViewtouchesBeginDelegate.h" @interface PP ...
- iOS自定义控件创建原理(持续更新)
前言 因为如果要创建各种自定义控件根据需求的不同会有很多的差别,所以我就在这里,分析一些自定义控件的创建实现方法 弹出视图 1.把要弹出的视图装在一个控制器里面,自定义转场动画 2.创建一个弹出视图, ...
- iOS自定义控件开发详解
http://blog.csdn.net/zhangao0086/article/details/45622875
- IOS知识小记
iOS开发 小知识点 http://www.cnblogs.com/tangbinblog/archive/2012/07/20/2601324.html Objective-C中的instancet ...
- Android开发之自定义组件和接口回调
说到自定义控件不得不提的就是接口回调,在Android开发中接口回调用的还是蛮多的.在这篇博客开始的时候呢,我想聊一下iOS的自定义控件.在iOS中自定义控件的思路是继承自UIView, 在UIVie ...
随机推荐
- Windows 8.1安装 Vmware10
之前在windows 8上安装的Vmware 9.0,已经激活了用的蛮好,可是自从上次自动更新系统到windows 8.1后,启动虚拟机时提示要激活 使用各种激活码与注册机都无效,就算注册表信息丢失但 ...
- 分布式缓存技术memcached学习(五)—— memcached java客户端的使用
Memcached的客户端简介 我们已经知道,memcached是一套分布式的缓存系统,memcached的服务端只是缓存数据的地方,并不能实现分布式,而memcached的客户端才是实现分布式的地方 ...
- Subsonic简单的语法整理
.查询方面 (查询所有数据记录[dataset读取方法]) Myuser.Query().ExecuteDataSet().Tables[]; Myuser.Query().ExecuteDataSe ...
- osg 示例程序解析之osgdelaunay
osg 示例程序解析之osgdelaunay 转自:http://lzchenheng.blog.163.com/blog/static/838335362010821103038928/ 本示例程序 ...
- C# 线程调用主线程中的控件
由于项目的需要,最近几天一直在做串口和数据库.由于C#使用的时间不长,所以在编写代码和调试的过程中总是遇到意想不到的问题,比如在使用串口接收数据的时候,在接收数据事件中想把接收的数据放入一个textb ...
- [LintCode] Delete Node in the Middle of Singly Linked List 在单链表的中间删除节点
Implement an algorithm to delete a node in the middle of a singly linked list, given only access to ...
- Java中线程的生命周期
首先简单的介绍一下线程: 进程:正在运行中的程序.其实进程就是一个应用程序运行时的内存分配空间. 线程:其实就是进程中的一条执行路径.进程负责的是应用程序的空间的标示.线程负责的是应用程序的执行顺序. ...
- 第 5 章 基础 DOM 和 CSS 操作
在常规的 DOM 元素中,我们可以使用 html()和 text()方法获取内部的数据.html()方法 可以获取或设置 html 内容,text()可以获取或设置文本内容. $('#box').ht ...
- poj1700-Crossing River(贪心算法)
一,题意: 只有一艘船,能乘2人,船的运行时间为2人中较多一人的时间,过去后还需一个人把船划回来,问把n个人运到对岸,最少需要多久.二,思路步骤: 想办法先把用时最多的2人,运过去,再把剩下来的人中用 ...
- html css 样式继承的问题
body 设置css中可以继承的属性:letter-spacing.word-spacing.white-space.line-height.color.font等 但有时,body的样式,不能在有的 ...