自定義UITableViewCell實現左滑動多菜單功能LeftSwipe

来源:http://www.cnblogs.com/tandaxia/archive/2016/04/01/5346659.html
-Advertisement-
Play Games

今天愚人節,小伙們,愚人節快樂! 實現一個小功能,滑動菜單,顯示隱藏的功能菜單, 先上圖: 這裡嘗試用了下使用三個方式來實現了這個功能: 1、使用自定義UITableViewCell + UISwipeGestureRecognizer + 代理 實現; 2、使用自定義UITableViewCell ...


  今天愚人節,小伙們,愚人節快樂!

  實現一個小功能,滑動菜單,顯示隱藏的功能菜單, 先上圖:

                         

這裡嘗試用了下使用三個方式來實現了這個功能:

1、使用自定義UITableViewCell + UISwipeGestureRecognizer + 代理 實現;

2、使用自定義UITableViewCell + UIPanGestureRecognizer + 代理 實現;

3、使用自定義UITableViewCell + UISwipeGestureRecognizer + block 實現。

 

註意點: 使用UIPanGestureRecognizer手勢實現左滑的時候,由於拖拽手勢的方向隨意性,導致與UITableViewController的下拉刷新手勢衝突了!

感覺還是用UISwipeGestureRecognizer清掃手勢實現好點!

 

部分代碼:

1、使用UISwipeGestureRecognizer  +  Delegate 

自定義UITableViewCell部分代碼:

 1 //
 2 //  TanTableViewCell.h
 3 //  Tan_SwipeTableViewCell
 4 //
 5 //  Created by PX_Mac on 16/3/25.
 6 //  Copyright © 2016年 PX_Mac. All rights reserved.
 7 //
 8 
 9 #import <UIKit/UIKit.h>
10 @class MemberModel;
11 @class TanTableViewCell;
12 
13 @protocol TanTableViewCellDelegate <NSObject>
14 
15 @optional
16 - (void)deleteMember: (TanTableViewCell *)cell; //協議方法:刪除會員
17 - (void)closeOtherCellLeftSwipe;  //關閉其他單元格的左滑
18 
19 @end
20 
21 @interface TanTableViewCell : UITableViewCell
22 
23 //靜態構造方法
24 + (instancetype)cellWithTableView: (UITableView *)tableView;
25 
26 @property (nonatomic, strong) MemberModel *model; //模型屬性
27 @property (nonatomic, weak) id<TanTableViewCellDelegate> delegate; //代理
28 
29 - (void)setData: (MemberModel *)model; //設置要顯示的數據
30 - (void)closeSwipe; //關閉滑動,恢複原樣(用於在滑動當前單元格時,把其他已經左滑的單元格關閉)
31 
32 @end
View Code
@implementation TanTableViewCell

+ (instancetype)cellWithTableView:(UITableView *)tableView{
    static NSString *reuseIdentity = @"tanCell";
    
    TanTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentity];
    
    if (cell == nil){
        cell = [[TanTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentity];
    }
    return cell;
}

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]){
        [self initSubControls]; //初始化子控制項
    }
    return self;
}

//初始化子控制項
- (void)initSubControls{
/*....... */

//3、給容器containerView綁定左右滑動清掃手勢
    UISwipeGestureRecognizer *leftSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)];
    leftSwipe.direction = UISwipeGestureRecognizerDirectionLeft; //設置向左清掃
    [self.containerView addGestureRecognizer:leftSwipe];
    
    UISwipeGestureRecognizer *rightSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)];
    rightSwipe.direction = UISwipeGestureRecognizerDirectionRight;//設置向右清掃
    [self.containerView addGestureRecognizer:rightSwipe];
    
    self.selectionStyle = UITableViewCellSelectionStyleNone; //設置單元格選中樣式
    [self.contentView bringSubviewToFront:self.containerView]; //設置containerView顯示在最上層
}

//左滑動和右滑動手勢
- (void)swipe: (UISwipeGestureRecognizer *)sender
{
    if (sender.direction == UISwipeGestureRecognizerDirectionLeft){
        if (self.isOpenLeft) return; //已經打開左滑,不再執行
        
        //開始左滑: 先調用代理關閉其他cell的左滑
        if ([self.delegate respondsToSelector:@selector(closeOtherCellLeftSwipe)])
            [self.delegate closeOtherCellLeftSwipe];
        
        [UIView animateWithDuration:0.5 animations:^{
            sender.view.center = CGPointMake(0, CELLHEIGHT * 0.5);
        }];
        self.isOpenLeft = YES;
    }
    else if (sender.direction == UISwipeGestureRecognizerDirectionRight){
        [self closeSwipe]; //關閉左滑
    }
}

//關閉左滑,恢複原狀
- (void)closeSwipe{
    if (!self.isOpenLeft) return; //還未打開左滑,不需要執行右滑
    
    [UIView animateWithDuration:0.5 animations:^{
        self.containerView.center = CGPointMake(SCREENWIDTH * 0.5, CELLHEIGHT * 0.5);
    }];
    self.isOpenLeft = NO;
}

//.....
@end
View Code

控制器部分代碼:

#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return self.dataArr.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    TanTableViewCell *cell = [TanTableViewCell cellWithTableView:tableView];
    cell.delegate = self;
    
    MemberModel *model = [self.dataArr objectAtIndex:indexPath.row];
    [cell setData:model];
    
    return cell;
}

#pragma mark - cell代理方法
//刪除單元格
- (void)deleteMember:(TanTableViewCell *)cell{
    NSIndexPath *path = [self.tableView indexPathForCell:cell]; //獲取cell所在位置
    //刪除數組中數據
    [self.dataArr removeObjectAtIndex:path.row];
    //刪除單元格
    [self.tableView deleteRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationLeft];
}

//關閉其他cell的左滑
- (void)closeOtherCellLeftSwipe{
    //迴圈顯示的cell
    for (TanTableViewCell *item in self.tableView.visibleCells) {
        [item closeSwipe];
    }
}
View Code

 

2、UIPanGestureRecognizer + 代理

自定義UITableViewCell部分代碼:

 1 //初始化子控制項
 2 - (void)initSubControls{
 3     /* ...... */
 4 
 5     //3、給容器containerView綁定拖動手勢
 6     UIPanGestureRecognizer *panGes = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
 7     [self.containerView addGestureRecognizer:panGes];
 8     self.panGes = panGes;
 9     
10     self.selectionStyle = UITableViewCellSelectionStyleNone; //設置單元格選中樣式
11     [self.contentView bringSubviewToFront:self.containerView]; //設置containerView顯示在最上層
12 }
13 
14 
15 //拖動手勢(拖拽手勢和UITableView的下拉刷新手勢有衝突,造成下拉刷新不能使用)
16 - (void)pan: (UIPanGestureRecognizer *)sender
17 {
18     //動畫結束時修正位置
19     if (sender.state == UIGestureRecognizerStateEnded){
20         
21         //關閉其他cell的左拖拽
22         if ([self.delegate respondsToSelector:@selector(closeOtherCellLeftPan:)])
23             [self.delegate closeOtherCellLeftPan: self];
24         
25         if (sender.view.frame.origin.x < -SCREENWIDTH * 0.25){
26             sender.view.transform = CGAffineTransformMakeTranslation(-SCREENWIDTH * 0.5, 0);
27             [sender setTranslation:CGPointZero inView:sender.view];  //必須歸0
28         }
29         else{
30             [self closeLeftPan];
31         }
32     }
33     
34     CGPoint point = [sender translationInView:self.contentView];
35     
36     CGFloat tx = sender.view.transform.tx;
37     
38     if (tx < - SCREENWIDTH * 0.5 || tx > 0) return;
39     
40     //形變
41     sender.view.transform = CGAffineTransformTranslate(sender.view.transform, point.x, 0);
42     [sender setTranslation:CGPointZero inView:sender.view];  //必須歸0
43 }
44 
45 //關閉左拖拽
46 - (void)closeLeftPan{
47     self.panGes.view.transform = CGAffineTransformMakeTranslation(0, 0);
48     [self.panGes setTranslation:CGPointZero inView:self.panGes.view];  //必須歸0
49 }
View Code

 

3、UISwipeGestureRecognizer + block 

自定義UITableViewCell部分代碼:

 1 //
 2 //  TanTableViewCell.h
 3 //  Tan_SwipeTableViewCell
 4 //
 5 //  Created by PX_Mac on 16/3/25.
 6 //  Copyright © 2016年 PX_Mac. All rights reserved.
 7 //
 8 
 9 #import <UIKit/UIKit.h>
10 @class MemberModel;
11 
12 @interface TanTableViewCell : UITableViewCell
13 
14 //靜態構造方法
15 + (instancetype)cellWithTableView: (UITableView *)tableView;
16 
17 @property (nonatomic, strong) MemberModel *model; //模型屬性
18 - (void)setData: (MemberModel *)model; //設置要顯示的數據
19 
20 @property (nonatomic, copy) void (^deleteMember)(); //刪除會員block回調方法
21 @property (nonatomic, copy) void (^closeOtherCellSwipe)(); //關閉其他cell的左滑
22 
23 - (void)closeLeftSwipe; //關閉左滑
24 
25 @end
View Code
 1 //左滑動和右滑動手勢
 2 - (void)swipe: (UISwipeGestureRecognizer *)sender
 3 {
 4     if (sender.direction == UISwipeGestureRecognizerDirectionLeft){
 5         if (self.isOpenLeft) return; //已經打開左滑,不再執行
 6         
 7         //開始左滑: 先調用block關閉其他可能左滑的cell
 8         if (self.closeOtherCellSwipe)
 9             self.closeOtherCellSwipe();
10         
11         [UIView animateWithDuration:0.5 animations:^{
12             sender.view.center = CGPointMake(0, CELLHEIGHT * 0.5);
13         }];
14         self.isOpenLeft = YES;
15     }
16     else if (sender.direction == UISwipeGestureRecognizerDirectionRight){
17         [self closeLeftSwipe]; //關閉左滑
18     }
19 }
20 
21 //關閉左滑,恢複原狀
22 - (void)closeLeftSwipe{
23     if (!self.isOpenLeft) return; //還未打開左滑,不需要執行右滑
24     
25     [UIView animateWithDuration:0.5 animations:^{
26         self.containerView.center = CGPointMake(SCREENWIDTH * 0.5, CELLHEIGHT * 0.5);
27     }];
28     self.isOpenLeft = NO;
29 }
View Code

控制器部分代碼:

 1 #pragma mark - 代理方法
 2 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
 3     return self.dataArr.count;
 4 }
 5 
 6 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
 7     TanTableViewCell *cell = [TanTableViewCell cellWithTableView:tableView];
 8     
 9     MemberModel *model = [self.dataArr objectAtIndex:indexPath.row];
10     [cell setData:model]; //設置數據
11     
12     __weak typeof(self) tempSelf = self;
13     __weak typeof(cell) tempCell = cell;
14     
15     //設置刪除cell回調block
16     cell.deleteMember = ^{
17         NSIndexPath *tempIndex = [tempSelf.tablView indexPathForCell:tempCell];
18         [tempSelf.dataArr removeObject:tempCell.model];
19         [tempSelf.tablView deleteRowsAtIndexPaths:@[tempIndex] withRowAnimation:UITableViewRowAnimationLeft];
20     };
21     
22     //設置當cell左滑時,關閉其他cell的左滑
23     cell.closeOtherCellSwipe = ^{
24         for (TanTableViewCell *item in tempSelf.tablView.visibleCells) {
25             if (item != tempCell) [item closeLeftSwipe];
26         }
27     };
28     
29     return cell;
30 }
View Code

 

DEMO下載:

github地址:https://github.com/xiaotanit/Tan_UITableViewCellLeftSwipe

csdn地址:http://download.csdn.net/detail/tandaxia/9479428

 

原文鏈接:http://www.cnblogs.com/tandaxia/p/5346659.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 首先來瞭解什麼包含塊,css包含塊是css標準佈局中的一個重要的概念,它是絕對定位的基礎。包含塊就是為絕對定位元素提供坐標偏移和顯示範圍的參照物,即確定絕對定位的偏移起點和百分比長度的參考。 由於ie瀏覽器在解析多層包含時會存在一些問題,在ie瀏覽器中只有當絕對定位的元素擁有層特征時才能準確解析,層 ...
  • Android起源與發展: Android操作系統最初在2003年的時候由Andy Rubin開發,主要支持手機。2005年8月由Google收購註資。2007年11月,Google與84家硬體製造商、軟體開發商及電信營運商組建開放手機聯盟共同研發改良Android系統。隨後Google以Apach ...
  • 今天把公司閑置的一臺Mac-mini重裝了下系統感覺用著速度還不錯,平時上班用的機器USB有些問題,所以打算用這台Mac。以往開發用Intellij Idea就夠用,但是這次項目引用的jar包太多,遭遇android Multi-Dex限制,所以用了Android Studio做分包。接下來得先下載 ...
  • 如果資料庫名為:“ifoData.db”,則它的路徑求法為 String pathDatabase=Mcontext.getDatabasePath("ifoData.db").getPath(); 其中Mcontext表示Context內容。 ...
  • GitHub:https://github.com/samvermette/SVProgressHUDSVProgressHUD和MBProgressHUD效果差不多,不過不需要使用協議,同時也不需要聲明實例。直接通過類方法進行調用即可: 可以使用以下方法來顯示狀態: 如果需要明確的進度,則使用以下 ...
  • 完整的開發一個android移動App需要經過從分解需求、架構設計到開發調試、測試、上線發佈等多個階段,在發佈後還會有產品功能上的迭代演進,此外還會面對性能、安全、無線網路質量等多方面的問題。 移動App的產品形態各不相同,有的是內容類,有的是工具類,有的是社交類,所以它們的業務邏輯所偏重的核心技術 ...
  • 源碼如下: 運行結果如下,在屏幕最右邊有一個紅色的P: 源碼解析: 1.首先程式跳轉至LABEL_BEGIN處,jmp LABEL_BEGIN。將ds、es、ss段寄存器全部初始化為當前代碼段。 2.初始化32位代碼段描述符 在實模式下,也就是8086的16位的CPU的定址方式是段x16+偏移,而在 ...
  • activity的佈局 佈局主要有五種: 1.LinearLayout(線性佈局) 可以利用orientation屬性來設置線性佈局是水平還是垂直 2.TableLayout(表格佈局) 3.RelativeLayout(相對佈局) 相對佈局是比較好的佈局方式,它是根據控制項的相對位置來佈局的,這個的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...