之前寫過一篇UITableView定制自定義cell左滑刪除按鈕小竅門,當(dāng)時電腦未升級xcode還沒有升級,所以當(dāng)使用ios11時候會發(fā)現(xiàn)存在一些問題,之前寫的那篇文章也有筆者提到此問題,為此最近升級了電腦系統(tǒng)版本以及同時升級了xcode9.打算對此問題好好的死磕一番。我覺得作為一個程序員來說,就是要有一顆死磕到底的心,這樣才會對技術(shù)方面有所成長,否則有一種一種始終在原地踏步的感覺。
<<一.視圖層級關(guān)系>>(xcode8 ios10 和xcode ios11)


<<二.對比分析>>
iOS11的左滑選項的視圖層級有了較大改變。最顯著的改變是UITableViewCell的子視圖變成了UITableView的子視圖??偨Y(jié)一下就是:
Xcode8編譯(ios10): UITableView -> UITableViewCell -> UITableViewCellDeleteConfirmationView -> _UITableViewCellActionButton
Xcode9編譯(ios11):UITableView -> UISwipeActionPullView -> UISwipeActionStandardButton
<<三.理論分析>>
針對于上篇文章沒有適配到ios11,顯然這樣是不行的,總不能跟產(chǎn)品說這就是ios11的個性吧。這樣顯然你可能也許就gg了。
為了同時支持iOS8-10和iOS11, 我把操作選項外觀的代碼統(tǒng)一放在UITableView的ViewController的- (void)viewDidLayoutSubviews實現(xiàn)。
為啥在viewDidLayoutSubviews中實現(xiàn)理由:
其一:因為iOS8-10中,左滑選項是UITableViewCell的子視圖,而在iOS11中,左滑選項變成了UITableView的子視圖。雖然可以用tabelCell.superview來獲取tableView,不過我認(rèn)為最好從高層級去操作低層級。所以統(tǒng)一在UITableView層處理。
其二:OS8-10的UITableViewCellDeleteConfirmationView子視圖出現(xiàn)得較晚。在代理方法willBeginEditingRowAtIndexPath中還沒有出現(xiàn),而在viewDidLayoutSubviews則可以保證子視圖出現(xiàn)。
<<四.簡要分析>>
1.定義一個屬性用來記錄當(dāng)前左滑的index
@property (strong, nonatomic) NSIndexPath* editingIndexPath; //當(dāng)前左滑cell的index,在代理方法中設(shè)置
2.調(diào)用viewDidLayoutSubviews方法
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
if (self.editingIndexPath){
[self configSwipeButtons];
}
}
3.針對不同的ios系統(tǒng)版本進行遍歷
- (void)configSwipeButtons{
// 獲取選項按鈕的reference
if (@available(iOS 11.0, *)){
// iOS 11層級 (Xcode 9編譯): UITableView -> UISwipeActionPullView
for (UIView *subview in self.tableView.subviews){
NSLog(@"%@-----%zd",subview,subview.subviews.count);
if ([subview isKindOfClass:NSClassFromString(@"UISwipeActionPullView")] && [subview.subviews count] >= 1){
// 和iOS 10的按鈕順序相反
UIButton *deleteButton = subview.subviews[0];
[self configDeleteButton:deleteButton];
}
}
}else{
// iOS 8-10層級 (Xcode 8編譯): UITableView -> UITableViewCell -> UITableViewCellDeleteConfirmationView
JYShopCell *tableCell = [self.tableView cellForRowAtIndexPath:self.editingIndexPath];
for (UIView *subview in tableCell.subviews){
NSLog(@"subview%@-----%zd",subview,subview.subviews.count);
if ([subview isKindOfClass:NSClassFromString(@"UITableViewCellDeleteConfirmationView")] && [subview.subviews count] >= 1){
UIButton *deleteButton = subview.subviews[0];
[self configDeleteButton:deleteButton];
}
}
}
}
- (void)configDeleteButton:(UIButton*)deleteButton{
if (deleteButton) {
[deleteButton setImage:[UIImage imageNamed:@"list_deleting"] forState:UIControlStateNormal];
[deleteButton setBackgroundColor:[UIColor colorWithHexString:@"F2F2F2"]];
}
}
4.代理實現(xiàn)
- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath{
self.editingIndexPath = indexPath;
[self.view setNeedsLayout]; // 觸發(fā)-(void)viewDidLayoutSubviews
}
- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath{
self.editingIndexPath = nil;
}