2013-01-18 169 views
3

我正在做的是,我有一個UITableview,我添加了UIButton作爲自定義視圖。我正在給每個按鈕添加標籤,並在操作方法中收到標籤。當我按下按鈕時,它會改變所選和未選按鈕的圖像,但是當我滾動它時,它會回到正常狀態。UITableview的滾動更改UIButton的圖像,UITableview滾動問題

這是在指數法我的行單元格

static NSString *CellIdentifier = @"Cell4"; 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) 
{ 
    cell = [self tableviewCellWithReuseIdentifierFollowing:CellIdentifier]; 
} 
followingButton = [UIButton buttonWithType:UIButtonTypeCustom]; 
[followingButton addTarget:self action:@selector(followingButtonpressed:)forControlEvents:UIControlEventTouchUpInside]; 
[followingButton setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal]; 
followingButton.frame = CGRectMake(220.0 ,20.0, 100, 40.0); 
[cell.contentView addSubview:followingButton]; 
NSLog(@"row--%d",indexPath.row); 
followingButton.tag=indexPath.row; 
NSLog(@"followingButton.tag--%d",followingButton.tag); 
[self configureCellFollowing:cell forIndexPath:indexPath]; 
return cell; 
} 

================== 

//Here is the action method 

-(void)followingButtonpressed:(id)sender 
{ 
    NSLog(@"sender tag --%d",[sender tag]); 
    UIButton *btnPly = (UIButton *)sender; 
    if([btnPly isSelected]) 
    { 
     [btnPly setSelected:NO]; 
     [btnPly setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal]; 
    } 
    else 
    { 
     [btnPly setSelected:YES]; 
     [btnPly setImage:[UIImage imageNamed:@"following_off12.png"] forState:UIControlStateNormal]; 
    } 
} 
+0

你有沒有想過如何解決這個問題?我現在有同樣的問題。 – Foo

回答

4

注:此代碼爲每行數據的創建小區(未重用小區)

你只需要改變的描述,可能有助於你

NSString *CellIdentifier = [NSString stringWithFormat:@"S%1dR%1d",indexPath.section,indexPath.row]; 

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

可能會解決你的問題:)

+0

謝謝......非常感謝。自從8小時以來我就這樣做了,現在我完成了。真的非常感謝您 –

+1

請記住,隨着您的表的增長,此解決方案可能會導致性能問題。最好的解決方案是讓數據源管理您的狀態,這樣您仍然可以保持單元重用性能。 – nebs

+0

@Nebs - 當用戶有很長的數據時會創建問題...但是我還在*我的答案中添加了* NOTE *(*它不會重用'UITableViewCell' *)它會爲每行創建單元格 – iPatel

0

這是因爲當你滾動那麼這段代碼調用

[followingButton setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal]; 

每次所以檢查現在

static NSString *CellIdentifier = @"Cell4"; 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) 
{ 
    cell = [self tableviewCellWithReuseIdentifierFollowing:CellIdentifier]; 

followingButton = [UIButton buttonWithType:UIButtonTypeCustom]; 
[followingButton addTarget:self action:@selector(followingButtonpressed:)forControlEvents:UIControlEventTouchUpInside]; 

[followingButton setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal]; 

followingButton.frame = CGRectMake(220.0 ,20.0, 100, 40.0); 
[cell.contentView addSubview:followingButton]; 

[self configureCellFollowing:cell forIndexPath:indexPath]; 
} 
return cell; 
} 
+0

嘗試過它,但它沒有解決問題,在滾動它再次將圖像更改爲正常狀態 –

2

你的按鈕「重置」的原因是因爲ause tableView:cellForRowAtIndexPath被多次調用(每當單元格即將可見時)。

每調用一次,您都會重新初始化您的按鈕並將圖像重置爲following.png(默認狀態)。這就是爲什麼當你滾動按鈕似乎重置。

您不能依靠細胞本身來保存狀態,因爲細胞每次都會重置。你需要把你的狀態移到別的地方(比如在一個數組實例變量中)。然後當你必須在tableView:cellForRowAtIndexPath中配置一個新的單元時,你可以將它初始化爲適當的狀態(基於數組)。

所以創建一個名爲myStateArray(或其他)一個NSMutableArray實例變量來存儲您的按鈕狀態,那麼你的cellForRowAtIndexPath應該更像:

static NSString *CellIdentifier = @"Cell4"; 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) 
{ 
    cell = [self tableviewCellWithReuseIdentifierFollowing:CellIdentifier]; 
} 
followingButton = [UIButton buttonWithType:UIButtonTypeCustom]; 
[followingButton addTarget:self action:@selector(followingButtonpressed:)forControlEvents:UIControlEventTouchUpInside]; 

// -- Fetch the state from your array 
BOOL buttonPressed = [[self.myStateArray objectAtIndex:indexPath.row] boolValue]; 

// -- Initialize the button state correctly 
[followingButton setSelected:buttonPressed]; 
if (buttonPressed) { 
    [followingButton setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal]; 
} else { 
    [followingButton setImage:[UIImage imageNamed:@"following_off12.png"] forState:UIControlStateNormal]; 
} 



followingButton.frame = CGRectMake(220.0 ,20.0, 100, 40.0); 
[cell.contentView addSubview:followingButton]; 
NSLog(@"row--%d",indexPath.row); 
followingButton.tag=indexPath.row; 
NSLog(@"followingButton.tag--%d",followingButton.tag); 
[self configureCellFollowing:cell forIndexPath:indexPath]; 
return cell; 
} 

然後在你按下按鈕請務必保存狀態:

-(void)followingButtonpressed:(id)sender 
{ 
    // -- Save the state 
    [self.myStateArray insertObject:[NSNumber numberWithBool:[btnPly isSelected]] atIndex:[sender tag]]; 

    NSLog(@"sender tag --%d",[sender tag]); 
    UIButton *btnPly = (UIButton *)sender; 
    if([btnPly isSelected]) 
    { 
     [btnPly setSelected:NO]; 
     [btnPly setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal]; 
    } 
    else 
    { 
     [btnPly setSelected:YES]; 
     [btnPly setImage:[UIImage imageNamed:@"following_off12.png"] forState:UIControlStateNormal]; 
    } 
} 
+0

您能否建議您在哪裏撰寫該聲明? –

+0

@Prateeksharma我用一些示例代碼更新了我的答案(它沒有經過測試,只是爲了給你一個想法)。 – nebs

+0

用數組也試過這種方式,但是當我滾動時它又移除了當前狀態並將其置於正常狀態 –

1

當我從代碼理解你創建的UIButton每當UITableView的詢問小區。在這兩種情況下,如果你創建一個新的單元格或者你使用了一個新的單元格。然後,您每創建一個按鈕,再創建一個按鈕。移動按鈕創建到細胞創造if所以你cellForRowAtIndexPath方法應該看起來像

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    static NSString *CellIdentifier = @"Cell4"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) 
    { 
     cell = [self tableviewCellWithReuseIdentifierFollowing:CellIdentifier]; 
     followingButton = [UIButton buttonWithType:UIButtonTypeCustom]; 
     [followingButton addTarget:self action:@selector(followingButtonpressed:)forControlEvents:UIControlEventTouchUpInside]; 
     [followingButton setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal]; 
     followingButton.frame = CGRectMake(220.0 ,20.0, 100, 40.0); 
     [cell.contentView addSubview:followingButton]; 
    } 
    NSLog(@"row--%d",indexPath.row); 
    followingButton.tag=indexPath.row; 
    NSLog(@"followingButton.tag--%d",followingButton.tag); 
    [self configureCellFollowing:cell forIndexPath:indexPath]; 
    return cell; 
} 

但是,這將不會被競爭你的問題的解決方案。正如您可能知道的那樣,UITableView使用「可重用」單元來減少系統內存使用量。它只使用一定數量的細胞來顯示目前的情況。所以在100個單元的表格中,它實際上會創建大約10個。而且它們都不會存儲所有數量按下/未按下按鈕的正確狀態。爲了達到正確的行爲,你必須拒絕使用標籤並改用一些模型邏輯。最簡單的方法 - 你將存儲按鈕狀態的NSMutableArray。在followingButtonpressed:方法中,您將正確的對象設置爲YES/NO,並在cellForRowAtIndexPath中讀取此值。下面

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    static NSString *CellIdentifier = @"Cell4"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) 
    { 
     cell = [self tableviewCellWithReuseIdentifierFollowing:CellIdentifier]; 
     followingButton = [UIButton buttonWithType:UIButtonTypeCustom]; 
     [followingButton addTarget:self action:@selector(followingButtonpressed:)forControlEvents:UIControlEventTouchUpInside]; 
     [followingButton setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal]; 
     followingButton.frame = CGRectMake(220.0 ,20.0, 100, 40.0); 
     [cell.contentView addSubview:followingButton]; 

     BOOL isSelected = [[statesArray objectAtIndex:btnPly.tag] boolValue]; 
     [self setState:isSelected forButton:followingButton]; 
    } 
    NSLog(@"row--%d",indexPath.row); 
    followingButton.tag=indexPath.row; 
    NSLog(@"followingButton.tag--%d",followingButton.tag); 
    [self configureCellFollowing:cell forIndexPath:indexPath]; 
    return cell; 
} 

-(void)followingButtonpressed:(id)sender 
{ 
    NSLog(@"sender tag --%d",[sender tag]); 
    UIButton *btnPly = (UIButton *)sender; 

    BOOL isSelected = [[statesArray objectAtIndex:btnPly.tag] boolValue]; 
    [statesArray replaceObjectAtIndex:btnPly.tag withObject:[NSNumber numberWithBool:!isSelected]]; 

    if(isSelected) 
    { 
     [self setState:NO forButton:btnPly]; 
    } 
    else 
    { 
     [self setState:YES forButton:btnPly]; 
    } 
} 

- (void) setState:(BOOL)state forButton:(UIButton *)button 
{ 
    if(state) 
    { 
     [button setSelected:NO]; 
     [button setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal]; 
    } 
    else 
    { 
     [button setSelected:YES]; 
     [button setImage:[UIImage imageNamed:@"following_off12.png"] forState:UIControlStateNormal]; 
    } 
} 

校驗碼在哪裏statesArray

NSMutableArray *statesArray = [NSMutableArray new]; 

,你必須創建和你某處類初始化。在statesArray中的對象計數必須與單元格int tableView的計數相同。

+0

[self tableviewCellWithReuseIdentifierFollowing:CellIdentifier] ;這是你實現的地方。 – 2014-09-01 09:38:30