之前寫(xiě)過(guò)一篇UITableView定制自定義cell左滑刪除按鈕小竅門(mén),當(dāng)時(shí)電腦未升級(jí)xcode還沒(méi)有升級(jí),所以當(dāng)使用ios11時(shí)候會(huì)發(fā)現(xiàn)存在一些問(wèn)題挥唠,之前寫(xiě)的那篇文章也有筆者提到此問(wèn)題,為此最近升級(jí)了電腦系統(tǒng)版本以及同時(shí)升級(jí)了xcode9.打算對(duì)此問(wèn)題好好的死磕一番律秃。我覺(jué)得作為一個(gè)程序員來(lái)說(shuō)祸挪,就是要有一顆死磕到底的心玖媚,這樣才會(huì)對(duì)技術(shù)方面有所成長(zhǎng),否則有一種一種始終在原地踏步的感覺(jué)坝锰。
<<一.視圖層級(jí)關(guān)系>>(xcode8 ios10 和xcode ios11)
<<二.對(duì)比分析>>
iOS11的左滑選項(xiàng)的視圖層級(jí)有了較大改變粹懒。最顯著的改變是UITableViewCell的子視圖變成了UITableView的子視圖∏昙叮總結(jié)一下就是:
Xcode8編譯(ios10): UITableView -> UITableViewCell -> UITableViewCellDeleteConfirmationView -> _UITableViewCellActionButton
Xcode9編譯(ios11):UITableView -> UISwipeActionPullView -> UISwipeActionStandardButton
<<三.理論分析>>
針對(duì)于上篇文章沒(méi)有適配到ios11,顯然這樣是不行的凫乖,總不能跟產(chǎn)品說(shuō)這就是ios11的個(gè)性吧。這樣顯然你可能也許就gg了弓颈。
為了同時(shí)支持iOS8-10和iOS11, 我把操作選項(xiàng)外觀的代碼統(tǒng)一放在UITableView的ViewController的- (void)viewDidLayoutSubviews
實(shí)現(xiàn)帽芽。
為啥在viewDidLayoutSubviews中實(shí)現(xiàn)理由:
其一:因?yàn)閕OS8-10中,左滑選項(xiàng)是UITableViewCell的子視圖翔冀,而在iOS11中导街,左滑選項(xiàng)變成了UITableView的子視圖。雖然可以用tabelCell.superview來(lái)獲取tableView纤子,不過(guò)我認(rèn)為最好從高層級(jí)去操作低層級(jí)搬瑰。所以統(tǒng)一在UITableView層處理。
其二:OS8-10的UITableViewCellDeleteConfirmationView子視圖出現(xiàn)得較晚控硼。在代理方法willBeginEditingRowAtIndexPath中還沒(méi)有出現(xiàn)泽论,而在viewDidLayoutSubviews則可以保證子視圖出現(xiàn)。
<<四.簡(jiǎn)要分析>>
1.定義一個(gè)屬性用來(lái)記錄當(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.針對(duì)不同的ios系統(tǒng)版本進(jìn)行遍歷
- (void)configSwipeButtons{
// 獲取選項(xiàng)按鈕的reference
if (@available(iOS 11.0, *)){
// iOS 11層級(jí) (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層級(jí) (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.代理實(shí)現(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;
}