先看效果 :
說下思路:首先要實現tableview的代理。共有幾個方法:
1:
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
return YES;
}
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewCellEditingStyleDelete ;
}
- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath{
WEAK_SELF;
UITableViewRowAction *deleteRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"刪除"handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
NSLog(@"點擊了刪除");
[tableView setEditing:NO animated:YES];
AddressRecord *record = weakSelf.addressArray[indexPath.row];
[weakSelf deleteAddress:record.id];
}];
deleteRowAction.backgroundColor = ColorRGB(83, 80, 84);
UITableViewRowAction *setDefaultAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"設置默認"handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
AddressRecord *record = weakSelf.addressArray[indexPath.row];
[tableView setEditing:NO animated:YES];
[weakSelf setDefaultAddress:record.id];
}];
setDefaultAction.backgroundColor = ColorRGB(169, 166, 170);
AddressRecord *record = self.addressArray[indexPath.row];
if (record.is_default) {
return @[deleteRowAction];
}else{
return @[deleteRowAction,setDefaultAction];
}
}
以上幾個方法能看懂什麼意思就不說了 調用這幾個方法就能實現側滑出現自定義button
在iOS11以上。新增了一個方法:
- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(11.0)){
WEAK_SELF;
if (@available(iOS 11.0, *)) {
UIContextualAction *deleteRowAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleNormal title:@"刪除" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
AddressRecord *record = weakSelf.addressArray[indexPath.row];
[weakSelf deleteAddress:record.id];
}];
UIContextualAction *editRowAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleNormal title:@"設置默認" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
AddressRecord *record = weakSelf.addressArray[indexPath.row];
[tableView setEditing:NO animated:YES];
[weakSelf setDefaultAddress:record.id];
}];
AddressRecord *record = self.addressArray[indexPath.row];
if (record.is_default) {
UISwipeActionsConfiguration *config = [UISwipeActionsConfiguration configurationWithActions:@[deleteRowAction]];
//設置全屏滑動時不自定響應事件
config.performsFirstActionWithFullSwipe = false;
return config;
}else{
UISwipeActionsConfiguration *config = [UISwipeActionsConfiguration configurationWithActions:@[deleteRowAction,editRowAction]];
//設置全屏滑動時不自定響應事件
config.performsFirstActionWithFullSwipe = false;
return config;
}
}else{
return nil;
}
}
這個方法的實現看起來有點熟悉,在iOS11以上的系統中測試的時候用力向左側滑會發現一個問題,側滑之後會自動執行第一個action的事件,你沒有點擊那個action卻執行了方法,比如我的demo中最右的action是刪除 那麼我測試的時候用力左滑之後會自動刪除掉當前cell 我以爲出bug了。後來查資料看到了這個方法,在iOS11以上的系統實現這個方法可以禁用掉左滑事件。同時自定義action的事件。由於裏面的代碼跟上面第一步的代理的action的代碼一樣,所以有些重複,不過能很好的解決這個bug。
3:剩下的就很簡單了,在controller中側滑事件發生後會觸發代理:
- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath {
[self.view setNeedsLayout];
}
在這個代理中讓self。view刷新UI,重繪,然後就會調用系統方法:
- (void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
[self configSwipeButtons];
}
configSwipeButtons方法中就是對tableview進行遍歷,找到action上面的各個button,對其進行自定義操作就可以。
4:說明:在iOS13和iOS11和iOS10以下這三部分系統,action所在的table的層級和名稱是不一樣的,所以要加以區分:
- (void)configSwipeButtons{
if (@available(iOS 13.0, *)) {
for (UIView *subview in self.tableView.subviews){
if ([subview isKindOfClass:NSClassFromString(@"_UITableViewCellSwipeContainerView")] ){
for (UIView *actionView in subview.subviews) {
if ([actionView isKindOfClass:NSClassFromString(@"UISwipeActionPullView")]) {
actionView.backgroundColor = COLOR(clearColor);
if (actionView.subviews.count >= 2) {
UIButton *deleteButton = actionView.subviews[1];
UIButton *readButton = actionView.subviews[0];
[self configDeleteButton:deleteButton];
[self configReadButton:readButton];
}else if (actionView.subviews.count <2){
UIButton *deleteButton = actionView.subviews[0];
[self configDeleteButton:deleteButton];
}
}
}
}
}
}else if (@available(iOS 11.0, *)){
// iOS 11層級 (Xcode 8編譯): UITableView -> UITableViewWrapperView -> UISwipeActionPullView
for (UIView *subview in self.tableView.subviews){
if ([subview isKindOfClass:NSClassFromString(@"UITableViewWrapperView")]){
for (UIView *actionView in subview.subviews){
if ([actionView isKindOfClass:NSClassFromString(@"UISwipeActionPullView")]){
actionView.backgroundColor = COLOR(clearColor);
if (actionView.subviews.count >= 2) {
UIButton *deleteButton = actionView.subviews[1];
UIButton *readButton = actionView.subviews[0];
[self configDeleteButton:deleteButton];
[self configReadButton:readButton];
}else if (actionView.subviews.count <2){
UIButton *deleteButton = actionView.subviews[0];
[self configDeleteButton:deleteButton];
}
}
}
}
}
}else{
// iOS 8-10層級: UITableView -> UITableViewCell -> UITableViewCellDeleteConfirmationView
AddressTableViewCell *tableCell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
for (UIView *subview in tableCell.subviews){
if ([subview isKindOfClass:NSClassFromString(@"UITableViewCellDeleteConfirmationView")] && [subview.subviews count] >= 2){
UIButton *deleteButton = subview.subviews[0];
UIButton *readButton = subview.subviews[1];
[self configDeleteButton:deleteButton];
[self configReadButton:readButton];
}
}
}
}
- (void)configDeleteButton:(UIButton*)deleteButton{
deleteButton.titleLabel.font = FONT_Regular(13);
[deleteButton setTitleColor:COLOR(whiteColor) forState:0];
[deleteButton setBackgroundImage:[UIImage imageWithColor:ColorRGB(80, 83, 86)] forState:0];
deleteButton.layer.cornerRadius = 10;
deleteButton.layer.masksToBounds = YES;
[deleteButton updateConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(W(65));
make.top.equalTo(H(10));
make.bottom.equalTo(-1);
}];
}
- (void)configReadButton:(UIButton*)readButton{
readButton.titleLabel.font = FONT_Regular(13);
[readButton setTitleColor:COLOR(whiteColor) forState:0];
[readButton setBackgroundImage:[UIImage imageWithColor:ColorRGB(169, 166, 170)] forState:0];
readButton.layer.cornerRadius = 10;
readButton.layer.masksToBounds = YES;
[readButton updateConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(W(65));
make.top.equalTo(H(10));
make.bottom.equalTo(-1);
}];
}
到此爲止,大功告成