我的表視圖上有一些單元格/行,當視圖被打開時應該被設定為 "選定"。在我下面的代碼中,如果資料源包含一個特定的用戶ID,就應該出現一個綠色的復選標記(這部分作業),并且該行應該是 "選定 "的。也就是說,選中的狀態似乎并不作業。我怎樣才能將一個單元格設定為選中狀態呢?
ViewController.m
-(UITableViewCell *)tableView。 (UITableView*)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
NSDictionary *client = self.sectionClients[indexPath.section][indexPath.row] 。
static NSString *ClientTableIdentifier = @"ClientTableViewCell" ;
ClientTableViewCell *cell = (ClientTableViewCell *)[self.tableView dequeueReusableCellWithIdentifier:ClientTableIdentifier]。
if (cell == nil)
{
NSArray *nib = [[NSBundle MainBundle] loadNibNamed: @"ClientTableViewCell" owner:self options:nil】。]
cell = [nib objectAtIndex:0] 。
}
NSString *photo = client[@"客戶照片"]。
cell.clientName.text = [NSString stringWithFormat:@"%@ %@", client[@"名字"], client[@"姓氏"]]。
cell.subtext.text = client[@"phone"]。
NSURL *imageUrl = [NSURL URLWithString:photo]。
[cell.clientPhoto setImageWithURL:imageUrl]。
if (self.selectionData != NULL && [[self. selectionData valueForKey:@"client ids"] containsString:client[@"nid"]] )
{
cell.greenCheck.image = [UIImage imageNamed:@"added.png"]。
[cell setSelected:YES]。
}
return cell。
}
uj5u.com熱心網友回復:
在一個單元格上呼叫setSelected只能設定該單元格的選擇狀態,而不是表格中的某一行。一個單元格的選擇狀態只是影響其外觀。它并不影響行本身的選擇狀態。
由于單元格可以被重復使用,你的cellForRowAtIndexPath函式也應該清除選擇狀態,如果該單元格被用于一個不應該被選擇的行。
為了將一個行放入選擇狀態,您還需要為您希望被選擇的每一行呼叫selectRowAtIndexPath,即使是那些當前未顯示的行。因此,您不應該從cellForRowAtIndexPath中呼叫它,因為這將只選擇實際上已經顯示的行。
我不確定何時是呼叫selectRowAtIndexPath的最佳時機。它必須是在表視圖為表中的每個部分呼叫numberOfRowsInSection之后。你可以嘗試從viewDidAppear中選擇行。如果當時表還沒有準備好,那么你可能需要跟蹤每節的numberOfRowsInSection被呼叫的時間。
uj5u.com熱心網友回復:
有很多要討論的,但給你幾個想法......
首先,你需要使用selectRowAtIndexPath來通知表視圖某行被選中。
一種方法是將你想要預選的行傳遞給表視圖控制器,然后在viewDidLayoutSubviews中選擇行。請注意,viewDidLayoutSubviews在整個控制器的生命周期中被多次呼叫,所以你只需要做一次。
此外,您需要確保在您的資料源中跟蹤選定的狀態。
假設我們傳遞一個NSNumber的陣列:
@interface ClientTableViewController : UITableViewController
@property (strong, nonatomic) NSArray *preSelectedRows。
@end
并使用一個非常簡單的物件模型,如:
@interface ClientObject : NSObject
@property (strong, nonatomic) NSString *name。
@property (assign, readwrite) BOOL selected;
@end
你將在viewDidLoad()中設定.selected屬性:
//為我們要預選的行設定.selected屬性。
for (NSNumber *n in _preSelectedRows) {
clientData[[n integerValue]].selected = YES;
然后,在viewDidLayoutSubviews:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews] 。
//viewDidLayoutSubviews在控制器的生命周期中被多次呼叫。
//所以我們只想做這一次。
if (_preSelectedRows) {
for (NSNumber *n in _preSelectedRows) {
NSIndexPath *p = [NSIndexPath indexPathForRow:[n integerValue] inSection:0] 。
[self.tableView selectRowAtIndexPath:p animated:NO scrollPosition:UITableViewScrollPositionNone] 。
}
//clear the array so we don't call this again[/span>
_preSelectedRows = nil;
}
}
你也可以通過讓你的cell類處理視覺表現來為自己節省大量的精力。就像這樣:
@interface ClientTableViewCell()
{
UIImage *selectedImg。
UIImage *unselectedImg。
}
@end
@implementation ClientTableViewCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *) reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]。
if (self) {
selectedImg = [UIImage systemImageNamed:@"checkmark.square"] 。
unselectedImg = [UIImage systemImageNamed:@"square"] 。
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated] 。
self.textLabel.textColor = selected ? [UIColor redColor] : [UIColor blackColor] 。
self.imageView.image = selected ? selectedImg : unselectedImg。
}
@end。
而你的cellForRowAt就變成了:
- (UITableViewCell *)tableView: (UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath {
ClientTableViewCell *cell = (ClientTableViewCell *)[tableView dequeueReusableCellWithIdentifier:clientTableIdentifier forIndexPath:indexPath] 。
//我們只需要設定名稱,因為單元格類將處理。
//選擇時的視覺外觀。
cell.textLabel.text = clientData[indexPath.row].name。
return cell;
下面是一個完整的例子。https://github.com/DonMag/PreSelectExample
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/307427.html
標籤:
