iOS開發系列之常用自訂控制項開發集—自訂UITableViewCell側滑菜單控制項開發

來源:互聯網
上載者:User

iOS開發系列之常用自訂控制項開發集—自訂UITableViewCell側滑菜單控制項開發

在很多app中就有UITableViewCell左滑出現菜單如系統刪除按鈕,但是系統的只能有一個,有很多需求需要個人化不僅可以放文字還可以放按鈕修改背景色建立多個功能表項目,那麼系統提供的肯定不適合,所以我們需要自己手工打造。
直接上代碼如下:
WHC_MenuCell.h 標頭檔如下:

////  WHC_MenuCell.m//  WHC_MenuCell////  Created by 吳海超 on 15/4/3.//  Copyright (c) 2015年 Sinosun Technology Co., Ltd. All rights reserved.//#import @class WHC_MenuCell;@protocol WHC_MenuCellDelegate - (BOOL)WHC_MenuCell:(WHC_MenuCell*)whcCell didPullCell:(NSInteger)index;            //拉動tableView的回調@end@interface WHC_MenuCell : UITableViewCell@property (nonatomic,assign)   CGFloat                 menuViewWidth;                //菜單總寬度@property (nonatomic,retain)   NSArray               * menuItemTitles;               //每個菜單的標題@property (nonatomic,retain)   NSArray               * menuItemTitleColors;          //每個菜單的文字顏色@property (nonatomic,retain)   NSArray               * menuItemBackImages;           //每個菜單的背景圖片@property (nonatomic,retain)   NSArray               * menuItemNormalImages;         //每個菜單正常的圖片@property (nonatomic,retain)   NSArray               * menuItemSelectedImages;       //每個菜單選中的圖片@property (nonatomic,retain)   NSArray               * menuItemBackColors;           //每個菜單的背景顏色@property (nonatomic,retain)   NSArray               * menuItemWidths;               //每個菜單的寬度@property (nonatomic,strong)   UIView                * ContentView;                  //自訂內容view@property (nonatomic,assign)   CGFloat                 fontSize;                     //字型大小@property (nonatomic,assign)   NSInteger               index;                        //cell下標@property (nonatomic,assign)   iddelegate;                     //cell代理//單擊功能表項目- (void)clickMenuItem:(UIButton*)sender;//關閉菜單- (BOOL)closeCellWithAnimation:(BOOL)b;//關閉批量菜單- (BOOL)closeCellWithTableView:(UITableView*)tableView index:(NSInteger)index animation:(BOOL)b;//開始或者正在拉開菜單- (void)startScrollviewCell:(BOOL)state x:(CGFloat)moveX;//結束拉開菜單- (void)didEndScrollViewCell:(BOOL)state;@end

WHC_MenuCell.m源檔案如下:

////  WHC_MenuCell.m//  WHC_MenuCell////  Created by 吳海超 on 15/4/3.//  Copyright (c) 2015年 Sinosun Technology Co., Ltd. All rights reserved.//#import "WHC_MenuCell.h"#define KWHC_MENUCELL_ANMATION_PADING (10.0)@interface WHC_MenuCell (){    BOOL                                  _isOpen;              //是否開啟菜單    BOOL                                  _isScorllClose;       //是否滾動關閉菜單    CGFloat                               _startX;              //儲存拉開菜單開始觸摸x座標    UIView                              * _menuView;            //菜單view    UIPanGestureRecognizer              * _panGesture;          //手勢}@end@implementation WHC_MenuCell//初始化UI- (void)initUI{    _panGesture = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePanGesture:)];    _panGesture.delegate = self;    [self.contentView addGestureRecognizer:_panGesture];    UITapGestureRecognizer  * tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleTapGestrue:)];    tapGesture.delegate = self;    [self.contentView addGestureRecognizer:tapGesture];    if(_menuItemTitles == nil){        _menuItemTitles = @[];    }    if(_menuItemBackImages == nil){        _menuItemBackImages = @[];    }    if(_menuItemBackColors == nil){        _menuItemBackColors = @[[UIColor redColor]];    }    if(_menuItemTitleColors == nil){        _menuItemTitleColors = @[[UIColor blackColor]];    }    if(_menuItemWidths == nil){        _menuItemWidths = @[];    }    if(_menuItemNormalImages == nil){        _menuItemNormalImages = @[];    }    if(_menuItemSelectedImages == nil){        _menuItemSelectedImages = @[];    }    CGFloat  _menuViewX = CGRectGetWidth(_ContentView.frame) - _menuViewWidth;    _menuView = [[UIView alloc]initWithFrame:CGRectMake(_menuViewX + CGRectGetMinX(_ContentView.frame), 0.0, _menuViewWidth, CGRectGetHeight(_ContentView.frame))];    _menuView.backgroundColor = [UIColor clearColor];    [self.contentView insertSubview:_menuView belowSubview:_ContentView];    NSInteger menuItemCount = _menuItemTitles.count;    NSInteger menuBackImageCount = _menuItemBackImages.count;    NSInteger menuBackColorCount = _menuItemBackColors.count;    NSInteger menuTitleColorCount = _menuItemTitleColors.count;    NSInteger menuItemWidthCount = _menuItemWidths.count;    NSInteger menuItemNormalImageCount = _menuItemNormalImages.count;    NSInteger menuItemSelectedImageCount = _menuItemSelectedImages.count;    CGFloat btnWidth = _menuViewWidth / (CGFloat)menuItemCount;    CGFloat (^currentWidth)(NSInteger i) = ^(NSInteger i){        CGFloat  width = 0.0;        for (NSInteger j = 0; j <= i ; j++) {            width += [_menuItemWidths[j] floatValue];        }        return width;    };    //建立功能表按鈕    for (NSInteger i = 0; i < menuItemCount; i++) {        UIButton  * btn = [UIButton buttonWithType:UIButtonTypeCustom];        btn.tag = i;        CGRect btnRc = CGRectMake(i * btnWidth, 0.0, btnWidth, CGRectGetHeight(_ContentView.frame));        btn.frame = btnRc;        if(menuItemWidthCount == menuItemCount){            btnRc.origin.x = currentWidth(i - 1);            btnRc.size.width = [_menuItemWidths[i] floatValue];            btn.frame = btnRc;        }        [btn setTitle:_menuItemTitles[i] forState:UIControlStateNormal];        NSInteger  titleColorIndex = i;        if(titleColorIndex >= menuTitleColorCount){            titleColorIndex = menuTitleColorCount - 1;            if(titleColorIndex < 0){                titleColorIndex = 0;            }        }        if(titleColorIndex < menuTitleColorCount){            [btn setTitleColor:_menuItemTitleColors[titleColorIndex] forState:UIControlStateNormal];        }        NSInteger  imageIndex = i;        if(imageIndex >= menuBackImageCount){            imageIndex = menuBackImageCount - 1;            if(imageIndex < 0){                imageIndex = 0;            }        }        if(imageIndex > menuBackImageCount){            [btn setBackgroundImage:[UIImage imageNamed:_menuItemBackImages[imageIndex]] forState:UIControlStateNormal];        }        NSInteger  colorIndex = i;        if(colorIndex >= menuBackColorCount){            colorIndex = menuBackColorCount - 1;            if(colorIndex < 0){                colorIndex = 0;            }        }        if(colorIndex < menuBackColorCount){            btn.backgroundColor = _menuItemBackColors[colorIndex];        }        if(i < menuItemNormalImageCount){            NSString  * imageName = _menuItemNormalImages[i];            if(imageName != nil && imageName.length){                [btn setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];            }            if(i < menuItemSelectedImageCount){                NSString  * selectedImageName = _menuItemSelectedImages[i];                if(selectedImageName != nil && selectedImageName.length){                    [btn setImage:[UIImage imageNamed:selectedImageName] forState:UIControlStateHighlighted];                }            }        }        btn.titleLabel.minimumScaleFactor = 0.1;        btn.titleLabel.adjustsFontSizeToFitWidth = YES;        if(_fontSize == 0.0){            _fontSize = 18.0;        }        btn.titleLabel.font = [UIFont boldSystemFontOfSize:_fontSize];        [btn addTarget:self action:@selector(clickMenuItem:) forControlEvents:UIControlEventTouchUpInside];        [_menuView addSubview:btn];    }}//載入xib- (void)awakeFromNib{    [self initUI];}- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];    if(self){    }    return self;}//設定滾動列表時菜單關閉狀態- (void)setIsScrollClose{    _isScorllClose = NO;}//下面兩個方法有子類實現屬於觸摸監聽方法- (void)startScrollviewCell:(BOOL)state x:(CGFloat)moveX{}- (void)didEndScrollViewCell:(BOOL)state{}//單擊功能表項目- (void)clickMenuItem:(UIButton *)sender{    [self closeCellWithAnimation:YES];}//批量關閉tableview上得多個cell菜單- (BOOL)closeCellWithTableView:(UITableView*)tableView index:(NSInteger)index animation:(BOOL)b{    NSArray  * indexPathArr = [tableView indexPathsForVisibleRows];    BOOL  handleResult = NO;    for (NSIndexPath * indexPath in indexPathArr) {        if(_index != indexPath.row && index > -1){            WHC_MenuCell * cell = (WHC_MenuCell *)[tableView cellForRowAtIndexPath:indexPath];            [cell setIsScrollClose];            if([cell closeCellWithAnimation:b]){                handleResult = YES;            }        }else if(index <= -1){            WHC_MenuCell * cell = (WHC_MenuCell *)[tableView cellForRowAtIndexPath:indexPath];            if(_index != indexPath.row){                [cell setIsScrollClose];            }            if([cell closeCellWithAnimation:b]){                handleResult = YES;            }        }    }    return handleResult;}//關閉cell菜單- (BOOL)closeCellWithAnimation:(BOOL)b{    BOOL isClose = NO;    if(_isOpen){        isClose = YES;        if(b){            [UIView animateWithDuration:0.2 animations:^{                _ContentView.transform = CGAffineTransformMakeTranslation(0.0, 0.0);            }completion:^(BOOL finished) {                _isOpen = NO;                [self didEndScrollViewCell:_isOpen];            }];        }else{            _ContentView.transform = CGAffineTransformMakeTranslation(0.0, 0.0);            _isOpen = NO;            [self didEndScrollViewCell:_isOpen];        }    }    return isClose;}- (void)setSelected:(BOOL)selected animated:(BOOL)animated {    [super setSelected:selected animated:animated];    // Configure the view for the selected state}//手勢處理- (void)handlePanGesture:(UIPanGestureRecognizer*)panGesure{    switch (panGesure.state) {        case UIGestureRecognizerStateBegan:{            _startX = _ContentView.transform.tx;            _isScorllClose = [_delegate WHC_MenuCell:self didPullCell:_index];        }            break;        case UIGestureRecognizerStateChanged:{            if(_isScorllClose && _isOpen == NO){                return;            }            CGFloat    currentX = _ContentView.transform.tx;            CGFloat    moveDistanceX = [panGesure translationInView:panGesure.view].x;            CGFloat    velocityX = [panGesure velocityInView:panGesure.view].x;            CGFloat    moveX = _startX + moveDistanceX;            if(velocityX > 0){//right                if(currentX >= KWHC_MENUCELL_ANMATION_PADING){                    [panGesure setTranslation:CGPointMake(KWHC_MENUCELL_ANMATION_PADING, 0.0) inView:panGesure.view];                    break;                }            }else{                if(currentX < -_menuViewWidth){                    moveX = currentX - 0.4;                    [panGesure setTranslation:CGPointMake(moveX, 0.0) inView:panGesure.view];                }            }            _ContentView.transform = CGAffineTransformMakeTranslation(moveX, 0.0);            [self startScrollviewCell:_isOpen x:moveDistanceX];        }            break;        case UIGestureRecognizerStateCancelled:        case UIGestureRecognizerStateEnded:{            _isScorllClose = NO;            if(_ContentView.transform.tx > 0.0){                [UIView animateWithDuration:0.2 animations:^{                    _ContentView.transform = CGAffineTransformMakeTranslation(-KWHC_MENUCELL_ANMATION_PADING, 0.0);                }completion:^(BOOL finished) {                    _isOpen = NO;                    [self didEndScrollViewCell:_isOpen];                    [UIView animateWithDuration:0.2 animations:^{                        _ContentView.transform = CGAffineTransformMakeTranslation(0.0, 0.0);                    }];                }];            }else if (_ContentView.transform.tx < 0){                CGFloat  tx  = fabsf(_ContentView.transform.tx);                if(tx < _menuViewWidth / 2.0 || (tx < _menuViewWidth && _isOpen)){                    [UIView animateWithDuration:0.2 animations:^{                        _ContentView.transform = CGAffineTransformMakeTranslation(0.0, 0.0);                    }completion:^(BOOL finished) {                        _isOpen = NO;                        [self didEndScrollViewCell:_isOpen];                    }];                }else{                    [UIView animateWithDuration:0.2 animations:^{                        _ContentView.transform = CGAffineTransformMakeTranslation(-_menuViewWidth, 0.0);                    }completion:^(BOOL finished) {                        _isOpen = YES;                        [self didEndScrollViewCell:_isOpen];                    }];                }            }        }            break;        default:            break;    }}- (void)handleTapGestrue:(UITapGestureRecognizer*)tapGesture{}#pragma mark - UIGestureRecognizerDelegate- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{    if([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]){        return [_delegate WHC_MenuCell:self didPullCell:-1];    }else if([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class] ]){        UIPanGestureRecognizer  * panGesture = (UIPanGestureRecognizer*)gestureRecognizer;        CGPoint                   velocityPoint = [panGesture velocityInView:panGesture.view];        if(fabsf(velocityPoint.x) > fabsf(velocityPoint.y)){            return YES;        }else{            _isScorllClose = [_delegate WHC_MenuCell:self didPullCell:-1];            return _isScorllClose;        }    }    return NO;}@end

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.