看了很多自定義的第三方例子,都有一個(gè)通病,就是自定義出來的視圖會(huì)跟隨Cell的ContentView劃動(dòng),而Native的是沒有這個(gè)情況的(總是屏幕右對(duì)齊),但TableView并沒有暴露自定義這個(gè)視圖的方法,怎么辦呢,自己動(dòng)手豐衣足食.
首先裝一個(gè)LLDB輔助工具Chisel,雖然不是必需,但有這個(gè)東西在調(diào)試時(shí)會(huì)方便一些,建議裝上( https://github.com/facebook/chisel ),接著就是在項(xiàng)目中建個(gè)能正常顯示刪除按鈕的TableView,大概就是這樣
@interface RootViewController()<UITableViewDelegate, UITableViewDataSource>
@end
@implementation RootViewController
- (void)viewDidLoad
{
[super viewDidLoad];
UITableView *tv = [[UITableView alloc] init];
tv.delegate = self;
tv.dataSource = self;
tv.frame = self.view.bounds;
[self.view addSubview:tv];
}
#pragma mark TableView代理
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 3;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 這里就簡單返回個(gè)CELL
UITableViewCell *cell = [[UITableViewCell alloc] init];
cell.textLabel.text = @"sma111case";
cell.contentView.backgroundColor = [UIColor greenColor];
return cell;
}
// 允許劃動(dòng)刪除
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
// 刪除按鈕的文字(其實(shí)就是間接返回刪除按鈕的長度,自定義視圖時(shí)可調(diào)節(jié)該文本的長度控制View的寬度)
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
return @"sma11case";
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleDelete;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
// 在這里下個(gè)斷點(diǎn),因?yàn)檫@個(gè)時(shí)候已經(jīng)生成刪除按鈕視圖,順手拿到點(diǎn)擊的Cell
sleep(1);
}
@end
在Sleep的地方下個(gè)斷,然后觸發(fā)刪除事件,此時(shí)應(yīng)該停在Sleep那行代碼,在LLDB中CMD+K清掉日志,然后使用 pviews cell
拿到CELL的視圖樹,大概是這樣子
<UITableViewCell: 0x7fa858667c80; frame = (0 88; 375 44); text = 'sma111case'; autoresize = W; gestureRecognizers = <NSArray: 0x7fa858464280>; layer = <CALayer: 0x7fa858668050>>
| <UITableViewCellDeleteConfirmationView: 0x7fa858461ad0; frame = (375.5 0; 117 44); clipsToBounds = YES; autoresize = H; layer = <CALayer: 0x7fa85842df20>>
| | <_UITableViewCellActionButton: 0x7fa858683fa0; frame = (0 0; 117 44); opaque = NO; autoresize = H; layer = <CALayer: 0x7fa8586844e0>>
| | | <UIButtonLabel: 0x7fa858684f80; frame = (15 11; 87 21.5); text = 'sma11case'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7fa858685420>>
| <UITableViewCellContentView: 0x7fa858668070; frame = (0 0; 375 43.5); gestureRecognizers = <NSArray: 0x7fa8586688e0>; layer = <CALayer: 0x7fa8586681f0>>
| | <UITableViewLabel: 0x7fa8586689f0; frame = (15 0; 345 43.5); text = 'sma111case'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7fa858668c00>>
| <_UITableViewCellSeparatorView: 0x7fa858669420; frame = (132.5 43.5; 243 0.5); layer = <CALayer: 0x7fa858646d80>>
注意 UITableViewCellDeleteConfirmationView
它就是刪除視圖,默認(rèn) backgroundColor
是紅色, _UITableViewCellActionButton
就是那個(gè)刪除按鈕,所以要自定義就是替換這兩個(gè)東西的事情啦,但要還要注意一個(gè)細(xì)節(jié),就是替換的時(shí)機(jī),這個(gè)刪除視圖是在顯示的時(shí)候創(chuàng)建的,然后在使用完畢后釋放,所以不能通過類似獲取屬性的形式獲取,因此,自定義的最好時(shí)機(jī)是在 layoutSubviews
方法中,大概就是這樣子
@implementation SCTableViewCell
- (void)layoutSubviews
{
[super layoutSubviews];
UIView *view = nil;
for (UIView *v in self.subviews)
{
if ([v isKindOfClass:NSClassFromString(@"UITableViewCellDeleteConfirmationView")])
{
view = v;
break;
}
}
// View=nil, subviews=nil, count=0都是false
if (view.subviews.count)
{
// 安全拿到Button
UIButton *button = view.subviews[0];
if (button)
{
// do sth....
}
}
}
最后,收工,祝各位看官愉快~~~
效果預(yù)覽:
Untitled.gif