iOS 自定义日历

释放双眼,带上耳机,听听看~!

自定义了一个日历,可以查看、选择日期,设置是否显示时间选择器。

首先看一下效果图:

 

大体说一下思路,核心点在于创建布局每个月的日期,点击年份月份只是刷新数据。每一个日期是一个视图,我这里用的是UIButton,通过循环添加到日期视图。获取日期一定是基于NSDate,通过NSCalendar获取到指定的某一年的某一月有多少天和第一天是星期几,这样就可以在循环中知道当前月份需要设置的初始日期位置以及需要设置的日期个数。其他就是展示和一些逻辑判断。

其中,年份和月份的下拉选项框是在之前一篇文章 iOS 自定义下拉选项框 —— HERO博客 上稍做修改。

下面贴上代码:

ViewController:

#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end
/*** ---------------分割线--------------- ***/
#import "ViewController.h"
#import "HWCalendar.h"
@interface ViewController ()<UITextFieldDelegate, HWCalendarDelegate>
@property (nonatomic, weak) HWCalendar *calendar;
@property (nonatomic, strong) UITextField *textField;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
//创建控件
[self creatControl];
}
- (void)creatControl
{
//输入框
_textField = [[UITextField alloc] initWithFrame:CGRectMake(7, 64, 400, 44)];
_textField.delegate = self;
_textField.layer.cornerRadius = 22;
_textField.layer.masksToBounds = YES;
_textField.placeholder = @"请设置日期";
_textField.textAlignment = NSTextAlignmentCenter;
_textField.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_textField];
//日历
HWCalendar *calendar = [[HWCalendar alloc] initWithFrame:CGRectMake(7, [UIScreen mainScreen].bounds.size.height, 400, 396)];
calendar.delegate = self;
calendar.showTimePicker = YES;
[self.view addSubview:calendar];
self.calendar = calendar;
}
#pragma mark - UITextFieldDelegate
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if (_calendar.frame.origin.y != [UIScreen mainScreen].bounds.size.height && _calendar) {
[_calendar dismiss];
return NO;
}else if (textField == _textField) {
[_calendar show];
return NO;
}
return YES;
}
#pragma mark - HWCalendarDelegate
- (void)calendar:(HWCalendar *)calendar didClickSureButtonWithDate:(NSString *)date
{
_textField.text = date;
}
@end

 

HWCalendar:

 

#import <UIKit/UIKit.h>
@class HWCalendar;
@protocol HWCalendarDelegate <NSObject>
- (void)calendar:(HWCalendar *)calendar didClickSureButtonWithDate:(NSString *)date;
@end
@interface HWCalendar : UIView
@property (nonatomic, assign) BOOL showTimePicker; //default is NO. doesn't show timePicker
@property (nonatomic, weak) id<HWCalendarDelegate> delegate;
- (void)show;
- (void)dismiss;
@end
/*** ---------------分割线--------------- ***/
#import "HWCalendar.h"
#import "HWOptionButton.h"
#define KCol 7
#define KBtnW 44
#define KBtnH 44
#define KMaxCount 37
#define KBtnTag 100
#define KTipsW 92
#define KShowYearsCount 100
#define KMainColor [UIColor colorWithRed:0.0f green:139/255.0f blue:125/255.0f alpha:1.0f]
#define KbackColor [UIColor colorWithRed:173/255.0f green:212/255.0f blue:208/255.0f alpha:1.0f]
@interface HWCalendar ()<UIPickerViewDelegate, UIPickerViewDataSource, HWOptionButtonDelegate>
@property (nonatomic, strong) NSArray *weekArray;
@property (nonatomic, strong) NSArray *timeArray;
@property (nonatomic, strong) NSArray *yearArray;
@property (nonatomic, strong) NSArray *monthArray;
@property (nonatomic, strong) UIPickerView *timePicker;
@property (nonatomic, weak) UIView *calendarView;
@property (nonatomic, weak) HWOptionButton *yearBtn;
@property (nonatomic, weak) HWOptionButton *monthBtn;
@property (nonatomic, weak) UILabel *weekLabel;
@property (nonatomic, weak) UILabel *yearLabel;
@property (nonatomic, weak) UILabel *monthLabel;
@property (nonatomic, weak) UILabel *dayLabel;
@property (nonatomic, assign) NSInteger year;
@property (nonatomic, assign) NSInteger month;
@property (nonatomic, assign) NSInteger day;
@property (nonatomic, assign) NSInteger hour;
@property (nonatomic, assign) NSInteger minute;
@property (nonatomic, assign) NSInteger currentYear;
@property (nonatomic, assign) NSInteger currentMonth;
@property (nonatomic, assign) NSInteger currentDay;
@end
@implementation HWCalendar
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
//获取当前时间
[self getCurrentDate];
//获取数据源
[self getDataSource];
//创建控件
[self creatControl];
//初始化设置
[self setDefaultInfo];
//刷新数据
[self reloadData];
}
return self;
}
- (void)getDataSource
{
_weekArray = @[@"日", @"一", @"二", @"三", @"四", @"五", @"六"];
_timeArray = @[@[@"00", @"01", @"02", @"03", @"04", @"05", @"06", @"07", @"08", @"09", @"10", @"11", @"12", @"13", @"14", @"15", @"16", @"17", @"18", @"19", @"20", @"21", @"22", @"23"], @[@"01", @"02", @"03", @"04", @"05", @"06", @"07", @"08", @"09", @"10", @"11", @"12", @"13", @"14", @"15", @"16", @"17", @"18", @"19", @"20", @"21", @"22", @"23", @"24", @"25", @"26", @"27", @"28", @"29", @"30", @"31", @"32", @"33", @"34", @"35", @"36", @"37", @"38", @"39", @"40", @"41", @"42", @"43", @"44", @"45", @"46", @"47", @"48", @"49", @"50", @"51", @"52", @"53", @"54", @"55", @"56", @"57", @"58", @"59"]];
NSInteger firstYear = _year - KShowYearsCount / 2;
NSMutableArray *yearArray = [NSMutableArray array];
for (int i = 0; i < KShowYearsCount; i++) {
[yearArray addObject:[NSString stringWithFormat:@"%ld", firstYear + i]];
}
_yearArray = yearArray;
_monthArray = @[@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10", @"11", @"12"];
}
- (void)setDefaultInfo
{
self.backgroundColor = [UIColor whiteColor];
[_timePicker selectRow:_hour inComponent:0 animated:NO];
[_timePicker selectRow:_minute - 1 inComponent:1 animated:NO];
_currentYear = _year;
_currentMonth = _month;
_currentDay = _day;
}
- (void)creatControl
{
//左侧显示视图
UIView *tipsView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, KTipsW, KBtnH * 8)];
tipsView.backgroundColor = KMainColor;
[self addSubview:tipsView];
//星期标签
UILabel *weekLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, KTipsW, KBtnH)];
weekLabel.backgroundColor = [UIColor colorWithRed:0.0f green:130/255.0f blue:116/255.0f alpha:1.0f];
weekLabel.textColor = [UIColor whiteColor];
weekLabel.textAlignment = NSTextAlignmentCenter;
[tipsView addSubview:weekLabel];
self.weekLabel = weekLabel;
//年份标签
UILabel *yearLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(weekLabel.frame) + 20, KTipsW, KBtnH)];
yearLabel.textColor = KbackColor;
yearLabel.textAlignment = NSTextAlignmentCenter;
yearLabel.font = [UIFont systemFontOfSize:26.0f];
[tipsView addSubview:yearLabel];
self.yearLabel = yearLabel;
//月份标签
UILabel *monthLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(yearLabel.frame), KTipsW, 26)];
monthLabel.textColor = [UIColor whiteColor];
monthLabel.textAlignment = NSTextAlignmentCenter;
monthLabel.font = [UIFont systemFontOfSize:26.0f];
[tipsView addSubview:monthLabel];
self.monthLabel = monthLabel;
//日期标签
UILabel *dayLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(monthLabel.frame) + 30, KTipsW, 120)];
dayLabel.textColor = [UIColor whiteColor];
dayLabel.textAlignment = NSTextAlignmentCenter;
dayLabel.font = [UIFont systemFontOfSize:76.0f];
[tipsView addSubview:dayLabel];
self.dayLabel = dayLabel;
CGFloat yearBtnW = 70.0f;
CGFloat monthbtnW = 60.0f;
CGFloat todayBtnW = 70.0f;
CGFloat padding = (self.bounds.size.width - KTipsW - yearBtnW - monthbtnW - todayBtnW - KBtnW * 2) * 0.25;
//年份按钮
HWOptionButton *yearBtn = [[HWOptionButton alloc] initWithFrame:CGRectMake(KTipsW + padding, 0, yearBtnW, KBtnH)];
yearBtn.array = _yearArray;
yearBtn.row = KShowYearsCount / 2;
yearBtn.delegate = self;
[self addSubview:yearBtn];
self.yearBtn = yearBtn;
//上一月
UIButton *preBtn = [[UIButton alloc] initWithFrame:CGRectMake(CGRectGetMaxX(yearBtn.frame) + padding, 0, KBtnW, KBtnH)];
[preBtn setImage:[UIImage imageNamed:@"left"] forState:UIControlStateNormal];
[preBtn addTarget:self action:@selector(preBtnOnClick) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:preBtn];
//月份按钮
HWOptionButton *monthBtn = [[HWOptionButton alloc] initWithFrame:CGRectMake(CGRectGetMaxX(preBtn.frame), 0, monthbtnW, KBtnH)];
monthBtn.array = _monthArray;
monthBtn.row = _month - 1;
monthBtn.delegate = self;
[self addSubview:monthBtn];
self.monthBtn = monthBtn;
//下一月
UIButton *nextBtn = [[UIButton alloc] initWithFrame:CGRectMake(CGRectGetMaxX(monthBtn.frame), 0, KBtnW, KBtnH)];
[nextBtn setImage:[UIImage imageNamed:@"right"] forState:UIControlStateNormal];
[nextBtn addTarget:self action:@selector(nextBtnOnClick) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:nextBtn];
//返回今天按钮
UIButton *backTodayBtn = [[UIButton alloc] initWithFrame:CGRectMake(CGRectGetMaxX(nextBtn.frame) + padding, 0, todayBtnW, KBtnH)];
backTodayBtn.titleLabel.font = [UIFont systemFontOfSize:14.0f];
[backTodayBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[backTodayBtn setTitle:@"返回今天" forState:UIControlStateNormal];
[backTodayBtn addTarget:self action:@selector(backTodayBtnOnClick) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:backTodayBtn];
//星期标签
for (int i = 0; i < _weekArray.count; i++) {
UILabel *week = [[UILabel alloc] initWithFrame:CGRectMake(KTipsW + KBtnH * i, KBtnH, KBtnH, KBtnH)];
week.textAlignment = NSTextAlignmentCenter;
week.text = _weekArray[i];
[self addSubview:week];
}
//日历核心视图
UIView *calendarView = [[UIView alloc] initWithFrame:CGRectMake(KTipsW, KBtnH * 2, KBtnW * 7, KBtnH * 6)];
[self addSubview:calendarView];
self.calendarView = calendarView;
//每一个日期用一个按钮去创建,当一个月的第一天是星期六并且有31天时为最多个数,5行零2个,共37个
for (int i = 0; i < KMaxCount; i++) {
CGFloat btnX = i % KCol * KBtnW;
CGFloat btnY = i / KCol * KBtnH;
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(btnX, btnY, KBtnW, KBtnH)];
btn.tag = i + KBtnTag;
btn.layer.cornerRadius = KBtnW * 0.5;
btn.layer.masksToBounds = YES;
[btn setTitle:[NSString stringWithFormat:@"%d", i + 1] forState:UIControlStateNormal];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn setTitleColor:KMainColor forState:UIControlStateSelected];
[btn setBackgroundImage:[self imageWithColor:KbackColor] forState:UIControlStateHighlighted];
[btn setBackgroundImage:[self imageWithColor:KbackColor] forState:UIControlStateSelected];
[btn addTarget:self action:@selector(dateBtnOnClick:) forControlEvents:UIControlEventTouchUpInside];
[calendarView addSubview:btn];
}
//确认按钮
UIButton *sureBtn = [[UIButton alloc] initWithFrame:CGRectMake(CGRectGetMinX(backTodayBtn.frame), CGRectGetMaxY(calendarView.frame), yearBtnW, KBtnH)];
sureBtn.titleLabel.font = [UIFont systemFontOfSize:16.0f];
[sureBtn setTitle:@"确定" forState:UIControlStateNormal];
[sureBtn setTitleColor:KMainColor forState:UIControlStateNormal];
[sureBtn addTarget:self action:@selector(sureBtnOnClick) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:sureBtn];
//取消按钮
UIButton *cancelBtn = [[UIButton alloc] initWithFrame:CGRectMake(CGRectGetMinX(sureBtn.frame) - yearBtnW, CGRectGetMinY(sureBtn.frame), yearBtnW, KBtnH)];
cancelBtn.titleLabel.font = [UIFont systemFontOfSize:16.0f];
[cancelBtn setTitle:@"取消" forState:UIControlStateNormal];
[cancelBtn setTitleColor:KMainColor forState:UIControlStateNormal];
[cancelBtn addTarget:self action:@selector(cancelBtnOnClick) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:cancelBtn];
//时间选择器
_timePicker = [[UIPickerView alloc] init];
_timePicker.backgroundColor = KMainColor;
_timePicker.hidden = YES;
_timePicker.delegate = self;
_timePicker.dataSource = self;
[self addSubview:_timePicker];
}
//set方法
- (void)setShowTimePicker:(BOOL)showTimePicker
{
_showTimePicker = showTimePicker;
if (showTimePicker) {
_timePicker.hidden = NO;
_dayLabel.frame = CGRectMake(0, CGRectGetMaxY(_monthLabel.frame) + 10, KTipsW, 120);
_timePicker.frame = CGRectMake(10, CGRectGetMaxY(_dayLabel.frame), KTipsW - 20, 88);
}else {
_timePicker.hidden = YES;
_dayLabel.frame = CGRectMake(0, CGRectGetMaxY(_monthLabel.frame) + 30, 200, 120);
}
}
//上一月按钮点击事件
- (void)preBtnOnClick
{
if (_month == 1) {
if (_yearBtn.row == 0) return;
_year --;
_month = 12;
_yearBtn.row --;
}else {
_month --;
}
_monthBtn.row = _month - 1;
[self reloadData];
}
//下一月按钮点击事件
- (void)nextBtnOnClick
{
if (_month == 12) {
if (_yearBtn.row == KShowYearsCount - 1) return;
_year ++;
_month = 1;
_yearBtn.row ++;
}else {
_month ++;
}
_monthBtn.row = _month - 1;
[self reloadData];
}
//返回今天
- (void)backTodayBtnOnClick
{
_year = _currentYear;
_month = _currentMonth;
_monthBtn.row = _month - 1;
_yearBtn.row = KShowYearsCount / 2;
[self reloadData];
}
//刷新数据
- (void)reloadData
{
NSInteger totalDays = [self numberOfDaysInMonth];
NSInteger firstDay = [self firstDayOfWeekInMonth];
_yearLabel.text = [NSString stringWithFormat:@"%ld", _year];
_monthLabel.text = [NSString stringWithFormat:@"%ld月", _month];
_yearBtn.title = [NSString stringWithFormat:@"%ld年", _year];
_monthBtn.title = [NSString stringWithFormat:@"%ld月", _month];
for (int i = 0; i < KMaxCount; i++) {
UIButton *btn = (UIButton *)[self.calendarView viewWithTag:i + KBtnTag];
btn.selected = NO;
if (i < firstDay - 1 || i > totalDays + firstDay - 2) {
btn.enabled = NO;
[btn setTitle:@"" forState:UIControlStateNormal];
}else {
if (_year == _currentYear && _month == _currentMonth) {
if (btn.tag - KBtnTag - (firstDay - 2) == _currentDay) {
btn.selected = YES;
_day = _currentDay;
_weekLabel.text = [NSString stringWithFormat:@"星期%@", _weekArray[(btn.tag - KBtnTag) % 7]];
_dayLabel.text = [NSString stringWithFormat:@"%ld", _day];
}
}else {
if (i == firstDay - 1) {
btn.selected = YES;
_day = btn.tag - KBtnTag - (firstDay - 2);
_weekLabel.text = [NSString stringWithFormat:@"星期%@", _weekArray[(btn.tag - KBtnTag) % 7]];
_dayLabel.text = [NSString stringWithFormat:@"%ld", _day];
}
}
btn.enabled = YES;
[btn setTitle:[NSString stringWithFormat:@"%ld", i - (firstDay - 1) + 1] forState:UIControlStateNormal];
}
}
}
//获取当前时间
- (void)getCurrentDate
{
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute fromDate:[NSDate date]];
_year = [components year];
_month = [components month];
_day = [components day];
_hour = [components hour];
_minute = [components minute];
}
//根据选中日期,获取相应NSDate
- (NSDate *)getSelectDate
{
//初始化NSDateComponents,设置为选中日期
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
dateComponents.year = _year;
dateComponents.month = _month;
return [[[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian] dateFromComponents:dateComponents];
}
//获取目标月份的天数
- (NSInteger)numberOfDaysInMonth
{
//获取选中日期月份的天数
return [[NSCalendar currentCalendar] rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:[self getSelectDate]].length;
}
//获取目标月份第一天星期几
- (NSInteger)firstDayOfWeekInMonth
{
//获取选中日期月份第一天星期几,因为默认日历顺序为“日一二三四五六”,所以这里返回的1对应星期日,2对应星期一,依次类推
return [[NSCalendar currentCalendar] ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitWeekOfYear forDate:[self getSelectDate]];
}
//根据颜色返回图片
- (UIImage *)imageWithColor:(UIColor *)color
{
CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
//选中日期时调用
- (void)dateBtnOnClick:(UIButton *)btn
{
_day = btn.tag - KBtnTag - ([self firstDayOfWeekInMonth] - 2);
_weekLabel.text = [NSString stringWithFormat:@"星期%@", _weekArray[(btn.tag - KBtnTag) % 7]];
_dayLabel.text = [NSString stringWithFormat:@"%ld", _day];
if (btn.selected) return;
for (int i = 0; i < KMaxCount; i++) {
UIButton *button = [self.calendarView viewWithTag:i + KBtnTag];
button.selected = NO;
}
btn.selected = YES;
}
#pragma mark - UIPickerViewDelegate
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return _timeArray.count;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [_timeArray[component] count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return _timeArray[component][row];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
NSString *time = _timeArray[component][row];
if (component == 0) {
_hour = [time integerValue];
} else if (component == 1) {
_minute = [time integerValue];
}
}
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
UILabel *pickerLabel = (UILabel *)view;
if (!pickerLabel) {
pickerLabel = [[UILabel alloc] init];
pickerLabel.textColor = [UIColor whiteColor];
pickerLabel.textAlignment = NSTextAlignmentCenter;
pickerLabel.font = [UIFont systemFontOfSize:20.0f];
}
pickerLabel.text = [self pickerView:pickerView titleForRow:row forComponent:component];
return pickerLabel;
}
#pragma mark - HWOptionButtonDelegate
- (void)didSelectOptionInHWOptionButton:(HWOptionButton *)optionButton
{
if (optionButton.title.length > 2) {
_year = [optionButton.title integerValue];
_yearBtn.title = [NSString stringWithFormat:@"%ld年", _year];
}else {
_month = [optionButton.title integerValue];
_monthBtn.title = [NSString stringWithFormat:@"%ld月", _month];
}
[self reloadData];
}
//确认按钮点击事件
- (void)sureBtnOnClick
{
[self dismiss];
NSString *date;
if (_showTimePicker) {
date = [NSString stringWithFormat:@"%ld-%02ld-%02ld %02ld:%02ld", _year, _month, _day, _hour, _minute];
}else {
date = [NSString stringWithFormat:@"%ld-%02ld-%02ld", _year, _month, _day];
}
if (_delegate && [_delegate respondsToSelector:@selector(calendar:didClickSureButtonWithDate:)]) {
[_delegate calendar:self didClickSureButtonWithDate:date];
}
}
//取消按钮点击事件
- (void)cancelBtnOnClick
{
[self dismiss];
}
//弹入视图
- (void)show
{
[UIView animateWithDuration:0.3f animations:^{
self.frame = CGRectMake(7, 140, self.bounds.size.width, self.bounds.size.height);
}];
}
//弹出视图
- (void)dismiss
{
[UIView animateWithDuration:0.3f animations:^{
self.frame = CGRectMake(7, [UIScreen mainScreen].bounds.size.height, self.bounds.size.width, self.bounds.size.height);
}];
}
@end

 

HWOptionButton:

#import <UIKit/UIKit.h>
@class HWOptionButton;
@protocol HWOptionButtonDelegate <NSObject>
//确认选项后,如有其它特殊操作,用此代理事件
- (void)didSelectOptionInHWOptionButton:(HWOptionButton *)optionButton;
@end
@interface HWOptionButton : UIView
@property (nonatomic, strong) NSArray *array;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, assign) NSInteger row;
@property (nonatomic, assign) BOOL showSearchBar; //default is NO.
@property (nonatomic, weak) id<HWOptionButtonDelegate> delegate;
@end
/*** ---------------分割线--------------- ***/
#import "HWOptionButton.h"
#define KMainW [UIScreen mainScreen].bounds.size.width
#define KMainH [UIScreen mainScreen].bounds.size.height
#define KMarginYWhenMoving 20.0f
#define KRowHeight 44.0f
#define KMaxShowLine 7
#define KFont [UIFont systemFontOfSize:13.0f]
#define KBackColor [UIColor whiteColor]
@interface HWOptionButton ()<UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate>
@property (nonatomic, strong) NSArray *searchArray;
@property (nonatomic, strong) UIWindow *cover;
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) UISearchBar *searchBar;
@property (nonatomic, weak) UIView *view;
@property (nonatomic, weak) UIButton *button;
@end
@implementation HWOptionButton
static NSString *KOptionButtonCell = @"KOptionButtonCell";
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self setup];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
if (self = [super initWithCoder:coder]) {
[self setup];
}
return self;
}
- (void)setup {
//按钮
UIButton *button = [[UIButton alloc] initWithFrame:self.bounds];
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
button.titleLabel.font = KFont;
[button setImage:[UIImage imageNamed:@"bottom"] forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:@"bottom"] forState:UIControlStateHighlighted];
[button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:button];
self.button = button;
//搜索框
_searchBar = [[UISearchBar alloc] init];
_searchBar.barTintColor = KBackColor;
_searchBar.layer.borderWidth = 1.0f;
_searchBar.layer.borderColor = [[UIColor blackColor] CGColor];
_searchBar.delegate = self;
_searchBar.keyboardType = UIKeyboardTypeASCIICapable;
//选项视图
_tableView = [[UITableView alloc] init];
_tableView.rowHeight = KRowHeight;
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_tableView.layer.borderWidth = 1.0f;
_tableView.layer.borderColor = [[UIColor blackColor] CGColor];
_tableView.dataSource = self;
_tableView.delegate = self;
_row = 0;
self.showSearchBar = NO;
}
- (void)buttonAction:(UIButton *)button
{
button.hidden = YES;
[self creatControl];
[self endEditing];
}
- (void)creatControl
{
//遮盖window
_cover = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
_cover.windowLevel = UIWindowLevelAlert;
_cover.hidden = NO;
//window视图
UIView *view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[_cover addSubview:view];
self.view = view;
//遮盖视图
UIView *backview = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
backview.backgroundColor = [UIColor colorWithRed:(0)/255.0 green:(0)/255.0 blue:(0)/255.0 alpha:0.0f];
[backview addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(Tap:)]];
[self.view addSubview:backview];
//坐标转换
CGRect frame = [self.superview convertRect:self.frame toView:self.view];
//显示选项按钮
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(frame.origin.x, frame.origin.y, self.frame.size.width, self.frame.size.height)];
button.titleLabel.font = KFont;
[button setTitle:_button.titleLabel.text forState:UIControlStateNormal];
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button addTarget:self action:@selector(btnOnClick) forControlEvents:UIControlEventTouchUpInside];
[button setImage:[UIImage imageNamed:@"bottom"] forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:@"bottom"] forState:UIControlStateHighlighted];
CGSize titleSize = [button.titleLabel.text boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:button.titleLabel.font} context:nil].size;
CGFloat imageLeftWidth = titleSize.width;
CGFloat titleLeftWidth = CGRectGetWidth(button.imageView.bounds);
button.imageEdgeInsets = UIEdgeInsetsMake(0, imageLeftWidth, 0, - imageLeftWidth);
button.titleEdgeInsets = UIEdgeInsetsMake(0, - titleLeftWidth, 0, titleLeftWidth);
[self.view addSubview:button];
//搜索框
if (_showSearchBar) {
_searchBar.frame = CGRectMake(frame.origin.x, CGRectGetMaxY(frame), frame.size.width, KRowHeight);
[self.view addSubview:_searchBar];
}
//设置初始位置
[_tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:_row inSection:0] animated:NO scrollPosition:UITableViewScrollPositionNone];
[_tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:_row inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
//设置frame
NSInteger rowCount = _showSearchBar ? KMaxShowLine - 1 : KMaxShowLine;
CGFloat tabelViewY = _showSearchBar ? CGRectGetMaxY(_searchBar.frame) : CGRectGetMaxY(frame);
if (_array.count <= rowCount) {
_tableView.frame = CGRectMake(frame.origin.x, tabelViewY, frame.size.width, _array.count * KRowHeight);
}else {
_tableView.frame = CGRectMake(frame.origin.x, tabelViewY, frame.size.width, rowCount * KRowHeight);
}
[self.view addSubview:_tableView];
}
- (void)setTitle:(NSString *)title
{
_title = title;
[_button setTitle:_title forState:UIControlStateNormal];
CGSize titleSize = [_title boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:_button.titleLabel.font} context:nil].size;
CGFloat imageLeftWidth = titleSize.width;
CGFloat titleLeftWidth = CGRectGetWidth(_button.imageView.bounds);
_button.imageEdgeInsets = UIEdgeInsetsMake(0, imageLeftWidth, 0, - imageLeftWidth);
_button.titleEdgeInsets = UIEdgeInsetsMake(0, - titleLeftWidth, 0, titleLeftWidth);
}
- (void)setArray:(NSArray *)array
{
_array = array;
self.searchArray = [_array copy];
[_tableView reloadData];
}
- (void)btnOnClick
{
[self dismissOptionAlert];
}
- (void)Tap:(UITapGestureRecognizer *)recognizer
{
[self dismissOptionAlert];
}
- (void)dismissOptionAlert
{
[_searchBar resignFirstResponder];
if (self.view.frame.origin.y == 0) {
[self removeCover];
}else {
[self searchBarTextDidEndEditing:_searchBar];
}
}
- (void)removeCover
{
[_searchBar resignFirstResponder];
_cover.hidden = YES;
_cover = nil;
_button.hidden = NO;
}
- (void)endEditing
{
[[[self findViewController] view] endEditing:YES];
}
- (UIViewController *)findViewController
{
id target = self;
while (target) {
target = ((UIResponder *)target).nextResponder;
if ([target isKindOfClass:[UIViewController class]]) {
break;
}
}
return target;
}
#pragma mark - UISearchBarDelegate
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
if (searchText.length > 0) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[c] %@", searchText];
_searchArray = [[_array filteredArrayUsingPredicate:predicate] copy];
}else {
_searchArray = [_array copy];
}
[_tableView reloadData];
}
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
UIView *view = self.superview;
while (view.superview) {
view = view.superview;
}
CGFloat Y = KMarginYWhenMoving - [self.superview convertRect:self.frame toView:self.view].origin.y;
[UIView animateWithDuration:0.22f animations:^{
view.frame = CGRectMake(0, Y, KMainW, KMainH);
self.view.frame = CGRectMake(0, Y, KMainW, KMainH);
}];
return YES;
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
UIView *view = self.superview;
while (view.superview) {
view = view.superview;
}
[UIView animateWithDuration:0.22f animations:^{
view.frame = CGRectMake(0, 0, KMainW, KMainH);
self.view.frame = CGRectMake(0, 0, KMainW, KMainH);
}completion:^(BOOL finished) {
[self removeCover];
}];
}
#pragma mark - tableViewDelegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _searchArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:KOptionButtonCell];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:KOptionButtonCell];
}
cell.textLabel.text = _searchArray[indexPath.row];
cell.backgroundColor = [UIColor whiteColor];
cell.textLabel.font = KFont;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
_row = indexPath.row;
self.title = _searchArray[_row];
[self dismissOptionAlert];
if (_delegate && [_delegate respondsToSelector:@selector(didSelectOptionInHWOptionButton:)]) {
[_delegate didSelectOptionInHWOptionButton:self];
}
}
@end

HWCalendar Demo 下载

原文链接:https://blog.csdn.net/hero_wqb/article/details/54377843

写博客的初心是希望大家共同交流成长,博主水平有限难免有偏颇之处,欢迎批评指正。

人已赞赏
iOS文章

iOS UITextField实用实现手机账号344格式

2020-2-21 5:15:30

iOS文章

iOS 字符串转化为类(进行控制器跳转)

2020-2-21 10:42:28

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索