iOS自定义实现日历控件

SZCalendarPicker.h


#import


@interface SZCalendarPicker : UIView


@property (nonatomic , strong) NSDate *date;

@property (nonatomic , strong) NSDate *today;

@property (nonatomic, copy) void(^calendarBlock)(NSInteger day, NSInteger month, NSInteger year);

@property (nonatomic , weak) IBOutlet UILabel *monthLabel;


+ (instancetype)showOnView:(UIView *)view;

 

@end




SZCalendarPicker.m


#import "SZCalendarPicker.h"

#import "YBCalendarCell.h"

#import "UIColor+ZXLazy.h"


NSString *const SZCalendarCellIdentifier = @"cell";


@interface SZCalendarPicker ()


@property (nonatomic , weak) IBOutlet UICollectionView *collectionView;

@property (nonatomic , weak) IBOutlet UIButton *previousButton;

@property (nonatomic , weak) IBOutlet UIButton *nextButton;

@property (nonatomic , strong) NSArray *weekDayArray;

@property (nonatomic , strong) UIView *mask;


@end


@implementation SZCalendarPicker



// Only override drawRect: if you perform custom drawing.

// An empty implementation adversely affects performance during animation.

- (void)drawRect:(CGRect)rect {

    // Drawing code

    

    [self addTap];

    [self addSwipe];

    [self show];


}



- (void)awakeFromNib

{

    [_collectionView registerClass:[YBCalendarCell class] forCellWithReuseIdentifier:SZCalendarCellIdentifier];

     _weekDayArray = @[@"",@"",@"",@"",@"",@"",@""];

}



- (void)customInterface

{

    CGFloat itemWidth = _collectionView.frame.size.width / 7;

    CGFloat itemHeight = _collectionView.frame.size.height / 7;

    

    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];

    layout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0);

    layout.itemSize = CGSizeMake(itemWidth, itemHeight);

    layout.minimumLineSpacing = 0;

    layout.minimumInteritemSpacing = 0;

    [_collectionView setCollectionViewLayout:layout animated:YES];

     

}


- (void)setDate:(NSDate *)date

{

    _date = date;


    NSString *weekDay = [self arabicNumeralsToChinese:[self weekDay:date]-1];

    [_monthLabel setText:[NSString stringWithFormat:@"%ld-%ld-%ld-星期%@",[self year:date],[self month:date],[self day:date],weekDay]];

    

    [_collectionView reloadData];

}


-(NSString *)arabicNumeralsToChinese:(NSInteger)number


{

    

    switch (number%7) {

            

        case 0:

            

            return @"";

            

            break;

            

        case 1:

            

            return @"";

            

            break;

            

        case 2:

            

            return @"";

            

            break;

            

        case 3:

            

            return @"";

            

            break;

            

        case 4:

            

            return @"";

            

            break;

            

        case 5:

            

            return @"";

            

            break;

            

        case 6:

            

            return @"";

            

            break;

            

        default:

            

            return nil;

            

            break;

            

    }

}


#pragma mark - date


- (NSInteger)day:(NSDate *)date{

    NSDateComponents *components = [[NSCalendar currentCalendar] components:(NSCalendarUnitDay) fromDate:date];

    return [components day];

}



- (NSInteger)month:(NSDate *)date{

    NSDateComponents *components = [[NSCalendar currentCalendar] components:(NSCalendarUnitMonth) fromDate:date];

    return [components month];

}


- (NSInteger)year:(NSDate *)date{

    NSDateComponents *components = [[NSCalendar currentCalendar] components:(NSCalendarUnitYear) fromDate:date];

    return [components year];

}



- (NSInteger)weekDay:(NSDate *)date{

    NSDateComponents *components = [[NSCalendar currentCalendar] components:(NSCalendarUnitWeekday) fromDate:date];

    return [components weekday];

}



- (NSInteger)firstWeekdayInThisMonth:(NSDate *)date{

    NSCalendar *calendar = [NSCalendar currentCalendar];

    

    [calendar setFirstWeekday:1];//1.Sun. 2.Mon. 3.Thes. 4.Wed. 5.Thur. 6.Fri. 7.Sat.

    NSDateComponents *comp = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:date];

    [comp setDay:1];

    NSDate *firstDayOfMonthDate = [calendar dateFromComponents:comp];

    

    NSUInteger firstWeekday = [calendar ordinalityOfUnit:NSCalendarUnitWeekday inUnit:NSCalendarUnitWeekOfMonth forDate:firstDayOfMonthDate];

    return firstWeekday - 1;

}


- (NSInteger)totaldaysInThisMonth:(NSDate *)date{

    NSRange totaldaysInMonth = [[NSCalendar currentCalendar] rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date];

    return totaldaysInMonth.length;

}


- (NSInteger)totaldaysInMonth:(NSDate *)date{

    NSRange daysInLastMonth = [[NSCalendar currentCalendar] rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date];

    return daysInLastMonth.length;

}


- (NSDate *)lastMonth:(NSDate *)date{

    NSDateComponents *dateComponents = [[NSDateComponents alloc] init];

    dateComponents.month = -1;

    NSDate *newDate = [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:date options:0];

    return newDate;

}


- (NSDate*)nextMonth:(NSDate *)date{

    NSDateComponents *dateComponents = [[NSDateComponents alloc] init];

    dateComponents.month = +1;

    NSDate *newDate = [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:date options:0];

    return newDate;

}


#pragma -mark collectionView delegate

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView

{

    return 2;

}


- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section

{

    if (section == 0) {

        return _weekDayArray.count;

    } else {

        return 42;

    }

}


- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath

{

    YBCalendarCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:SZCalendarCellIdentifier forIndexPath:indexPath];

    if (indexPath.section == 0) {

        [cell.dateLabel setText:_weekDayArray[indexPath.row]];

        [cell.dateLabel setTextColor:[UIColor colorWithHexString:@"#15cc9c"]];

    } else {

        NSInteger daysInThisMonth = [self totaldaysInMonth:_date];

        NSInteger firstWeekday = [self firstWeekdayInThisMonth:_date];

        

        NSInteger day = 0;

        NSInteger i = indexPath.row;

        

        if (i < firstWeekday) {

            [cell.dateLabel setText:@""];

            

        }else if (i > firstWeekday + daysInThisMonth - 1){

            [cell.dateLabel setText:@""];

        }else{

            day = i - firstWeekday + 1;

            if (day == 1) {

                

                [cell.dateLabel setText:[NSString stringWithFormat:@"%ld",[self month:_date]]];

                [cell.dateLabel setTextColor:[UIColor colorWithHexString:@"#6f6f6f"]];

                

            }else{

                

                

                [cell.dateLabel setText:[NSString stringWithFormat:@"%ld",day]];

                [cell.dateLabel setTextColor:[UIColor colorWithHexString:@"#6f6f6f"]];

            }

            

            

            //this month

            if ([_today isEqualToDate:_date]) {

                if (day == [self day:_date]) {

                    [cell.dateLabel setTextColor:[UIColor colorWithHexString:@"#4898eb"]];

                    cell.dateLabel.text = @"今天";

                } else if (day > [self day:_date]) {

                    [cell.dateLabel setTextColor:[UIColor colorWithHexString:@"#cbcbcb"]];

                }

            } else if ([_today compare:_date] == NSOrderedAscending) {

                [cell.dateLabel setTextColor:[UIColor colorWithHexString:@"#cbcbcb"]];

            }

        }

    }

    return cell;

}


- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath

{

    if (indexPath.section == 1) {

        NSInteger daysInThisMonth = [self totaldaysInMonth:_date];

        NSInteger firstWeekday = [self firstWeekdayInThisMonth:_date];

        

        NSInteger day = 0;

        NSInteger i = indexPath.row;

        

        if (i >= firstWeekday && i <= firstWeekday + daysInThisMonth - 1) {

            day = i - firstWeekday + 1;

            

            //this month

            if ([_today isEqualToDate:_date]) {

                if (day <= [self day:_date]) {

                    return YES;

                }

            } else if ([_today compare:_date] == NSOrderedDescending) {

                return YES;

            }

        }

    }

    return NO;

}


- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath

{

    NSDateComponents *comp = [[NSCalendar currentCalendar] components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekday) fromDate:self.date];

    NSInteger firstWeekday = [self firstWeekdayInThisMonth:_date];

    

    NSInteger day = 0;

    NSInteger i = indexPath.row;

    day = i - firstWeekday + 1;

    

    

    NSString *weekDay = [self arabicNumeralsToChinese:i];

    

    [_monthLabel setText:[NSString stringWithFormat:@"%ld-%ld-%ld-星期%@",[comp year],[comp month],day,weekDay]];

    

    if (self.calendarBlock) {

        self.calendarBlock(day, [comp month], [comp year]);

        

    }

    

    

   

    

//    [self hide];

}


- (IBAction)previouseAction:(UIButton *)sender

{

    [UIView transitionWithView:self duration:0.5 options:UIViewAnimationOptionTransitionCurlDown animations:^(void) {

        self.date = [self lastMonth:self.date];

    } completion:nil];

}


- (IBAction)nexAction:(UIButton *)sender

{

    [UIView transitionWithView:self duration:0.5 options:UIViewAnimationOptionTransitionCurlUp animations:^(void) {

        self.date = [self nextMonth:self.date];

    } completion:nil];

}


+ (instancetype)showOnView:(UIView *)view

{

    SZCalendarPicker *calendarPicker = [[[NSBundle mainBundle] loadNibNamed:@"SZCalendarPicker" owner:self options:nil] firstObject];

    calendarPicker.mask = [[UIView alloc] initWithFrame:view.bounds];

//    calendarPicker.mask.backgroundColor = [UIColor blackColor];

    calendarPicker.mask.alpha = 0.3;

    [view addSubview:calendarPicker.mask];

    [view addSubview:calendarPicker];

    return calendarPicker;

}


- (void)show

{

    self.transform = CGAffineTransformTranslate(self.transform, 0, - self.frame.size.height);

    [UIView animateWithDuration:0.5 animations:^(void) {

        self.transform = CGAffineTransformIdentity;

    } completion:^(BOOL isFinished) {

        [self customInterface];

    }];

}


- (void)hide

{

    [UIView animateWithDuration:0.5 animations:^(void) {

        self.transform = CGAffineTransformTranslate(self.transform, 0, - self.frame.size.height);

        self.mask.alpha = 0;

    } completion:^(BOOL isFinished) {

        [self.mask removeFromSuperview];

        [self removeFromSuperview];

    }];

}



- (void)addSwipe

{

    UISwipeGestureRecognizer *swipLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(nexAction:)];

    swipLeft.direction = UISwipeGestureRecognizerDirectionLeft;

    [self addGestureRecognizer:swipLeft];

    

    UISwipeGestureRecognizer *swipRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(previouseAction:)];

    swipRight.direction = UISwipeGestureRecognizerDirectionRight;

    [self addGestureRecognizer:swipRight];

}


- (void)addTap

{

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hide)];

    [self.mask addGestureRecognizer:tap];

}

 

@end




使用了xib


Previous Button

Next Button

Month Label

Collection View(Collection View Flow Layout)


YBCalendarCell.h


#import


@interface YBCalendarCell : UICollectionViewCell


@property (nonatomic , strong) UILabel *dateLabel;


 

@end



YBCalendarCell.m


#import "YBCalendarCell.h"


@implementation YBCalendarCell


- (UILabel *)dateLabel

{

    if (!_dateLabel) {

        _dateLabel = [[UILabel alloc] initWithFrame:self.bounds];

        [_dateLabel setTextAlignment:NSTextAlignmentCenter];

        [_dateLabel setFont:[UIFont systemFontOfSize:17]];

        [self addSubview:_dateLabel];

    }

    return _dateLabel;

}


 

@end


 

YBCalendarViewController.m


#import "YBCalendarViewController.h"

#import "SZCalendarPicker.h"

@interface YBCalendarViewController ()


@property(nonatomic,strong)UIButton *btn;



@end


@implementation YBCalendarViewController


- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view.

    

    self.view.backgroundColor = [UIColor blueColor];

    

    [self settingBtn];

    

}





-(void)settingBtn {

    

    

    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];

    

    btn.frame = CGRectMake(self.view.width/2 - 50, 64, 100, 25);

    

    btn.backgroundColor = [UIColor orangeColor];

    

    [btn addTarget:self action:@selector(Click) forControlEvents:UIControlEventTouchUpInside];

    

    [self.view addSubview:btn];

    

    self.btn = btn;


}



-(void)Click {

    

    SZCalendarPicker *calendarPicker = [SZCalendarPicker showOnView:self.view];

    calendarPicker.today = [NSDate date];

    calendarPicker.date = calendarPicker.today;

    calendarPicker.frame = CGRectMake(0, 100, self.view.frame.size.width, 352);

    calendarPicker.calendarBlock = ^(NSInteger day, NSInteger month, NSInteger year){

        

        NSLog(@"%ld-%ld-%ld", year,month,day);

     


    };

    

}


@end




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用SwiftUI自定义iOS分段控件可以通过以下步骤实现: 1. 创建一个新的SwiftUI View,命名为SegmentedControl。 2. 在SegmentedControl中定义一个枚举类型,用于表示分段控件中的选项。 3. 在SegmentedControl中定义一个@Binding属性用于绑定选中的选项。 4. 在SegmentedControl中使用ForEach循环遍历所有的选项,并将它们显示在分段控件中。 5. 在ForEach循环中,使用Button显示每一个选项,并在按钮的action中更新选中的选项。 6. 为分段控件添加样式,例如设置选中的选项的背景色和字体颜色等。 下面是一个简单的示例代码: ```swift enum SegmentedOption: String, CaseIterable { case option1 case option2 case option3 } struct SegmentedControl: View { @Binding var selectedOption: SegmentedOption var body: some View { HStack { ForEach(SegmentedOption.allCases, id: \.self) { option in Button(action: { self.selectedOption = option }) { Text(option.rawValue) .foregroundColor(self.selectedOption == option ? .white : .black) .padding(.horizontal, 20) .padding(.vertical, 10) .background(self.selectedOption == option ? Color.blue : Color.gray) .cornerRadius(10) } } } } } ``` 在使用时,只需要将SegmentedControl添加到需要显示的View中,并将选中的选项绑定到某个属性即可。例如: ```swift struct ContentView: View { @State private var selectedOption: SegmentedOption = .option1 var body: some View { VStack { SegmentedControl(selectedOption: $selectedOption) Text("Selected option: \(selectedOption.rawValue)") } } } ``` 这样就可以在界面上显示一个自定义iOS分段控件了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值