本文基于 XYInfomationSection v1.2.0 文檔,核心功能為支持長按重新排序
version: 1.2.0
date: 2021-7-31
author: xiaoyouPrince
此版本核心:
支持長按滑動內(nèi)部 Cell 進(jìn)行重新排序
設(shè)計背景
系統(tǒng) UITableView 支持編輯模式,但是移動 cell 重新排序無法自定義樣式缩擂。編輯模式下 UITableViewCell 會自動切換到 editingMode 的樣式。
長按拖動 cell 排序的需求灾前,恰好是一個常見的需求,在研究之后孟辑,決定為 XYInfomationSection 新添加長按滑動功能哎甲。
對外新增 API:
1. 設(shè)置為編輯模式,支持長按排序扑浸, default is NO
@property (nonatomic, assign, getter=isEditMode) BOOL editMode;
2. 自定義 cell 長按時樣式
cell 長按選中之后可自定義設(shè)置 cell 樣式烧给,入?yún)楸贿x中 cell 截圖,返回值為 UIView 對象喝噪,如無需自定義就不用實(shí)現(xiàn)此 block础嫡。 返回值可以直接為修改過的原截圖,也可以是自定義 view
@property (nonatomic, copy) UIView *(^customMovableCellwithSnap)(UIImageView *cellSnap);
3. UI 移動操作完成回調(diào)
cell 移動完成會回調(diào)此 block, 可在此 Block 中確定更新完是否使用新數(shù)據(jù)榴鼎。
默認(rèn)不實(shí)現(xiàn)此 block 就會使用新數(shù)據(jù)伯诬。如果請求網(wǎng)絡(luò),則刷新數(shù)據(jù)即可巫财。
@property (nonatomic, copy) void (^sectionCellHasMoved)(XYInfomationSection *section, NSArray *oldData);
/// 示例代碼
section.sectionCellHasMoved = ^(XYInfomationSection * _Nonnull section, NSArray * _Nonnull oldData) {
/// 執(zhí)行具體操作盗似,確定是否可以移動成功,成功/失敗需手動刷新數(shù)據(jù)
if (success) {
// 確定可以成功,無需刷新
}else{ // 如確定移動失敗平项,就需要手動使用舊數(shù)據(jù)刷新 section
[section refreshSectionWithDataArray:oldData];
}
};
4. 直接移動 內(nèi)部cell
- (void)moveCellFrom:(NSInteger)fromIndex to:(NSInteger)toIndex;
- (void)moveCellFrom:(NSInteger)fromIndex to:(NSInteger)toIndex completed:(nullable dispatch_block_t)completed;
內(nèi)部邏輯與實(shí)現(xiàn)
對外邏輯僅提供幾個簡單接口赫舒,對內(nèi)相對復(fù)雜一些。但整體邏輯并不復(fù)雜闽瓢,如下:
用戶長按cell ??
長按手勢被section對象攔截并實(shí)現(xiàn) ??
長按狀態(tài)開始:記錄當(dāng)前數(shù)據(jù)接癌,創(chuàng)建相關(guān)臨時數(shù)據(jù),支持自定義cell被長按選中樣式 ??
長按狀態(tài)移動:處理cell移動動畫扣讼,相關(guān)臨時數(shù)據(jù)修改 ??
長按狀態(tài)結(jié)束:處理最終動畫缺猛,如果有實(shí)現(xiàn)cell移動完成回調(diào)則進(jìn)行回調(diào)。
關(guān)于 UITableView 的 cell 移動調(diào)研
如果只是實(shí)現(xiàn)移動 UITableViewCell椭符,系統(tǒng)自帶的 API 即可搞定荔燎。
調(diào)用方法 [tableView setEditing:YES animated:YES]; 即可使 tableView 進(jìn)入編輯模式。然后實(shí)現(xiàn)下面的方法即可開啟移動 cell销钝。
//默認(rèn)編輯模式下有咨,每個cell左邊有個紅色的刪除按鈕,設(shè)置為None即可去掉
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleNone;
}
//是否允許indexPath的cell移動
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
//更新數(shù)據(jù)源
}
用系統(tǒng)的方法有幾個缺點(diǎn):
- 需要用一個開關(guān)去控制編輯狀態(tài)曙搬,不方便摔吏;
- 移動cell的時候cell右邊有個指示圖標(biāo),左邊也會縮進(jìn)出一個指示位(UITableViewCellEditingStyleNone可設(shè)置其無樣式纵装,但是站位會在)【菽常看著不爽橡娄;
- 被移動cell的樣式不能自己定制。
小結(jié)
綜上所述癣籽,UITableView 不能很好實(shí)現(xiàn)長按移動 cell挽唉。 如果有此需求,在列表不是很大情況下筷狼,可嘗試使用 XYInfomationSection 替換.
GitHub 地址: XYInfomationSection