Iphone 更新原始UITableView中第二个UITableView中的选择

Iphone 更新原始UITableView中第二个UITableView中的选择,iphone,xcode,uitableview,Iphone,Xcode,Uitableview,我无法使用第二个UITableView中的设置更新第一个UITableView 用户单击firstTableView中的一行,从而显示secondTableView。当用户选择一行时,secondTableView消失,firstTableView重新出现。但是,数据没有更新 我尝试在firstTableView中使用以下内容: - (void) viewWillAppear:(BOOL)animated { // (verified it's defenitely section 2

我无法使用第二个UITableView中的设置更新第一个UITableView

用户单击firstTableView中的一行,从而显示secondTableView。当用户选择一行时,secondTableView消失,firstTableView重新出现。但是,数据没有更新

我尝试在firstTableView中使用以下内容:

- (void) viewWillAppear:(BOOL)animated {

    // (verified it's defenitely section 2, row 0 by logging it before and after...)
    // (also verified that the source data has been updated before viewWillAppear is called...)

    NSIndexPath *durPath = [NSIndexPath indexPathForRow:0 inSection:2];
    NSArray *paths = [NSArray arrayWithObject:durPath];

   [self.firstTableView reloadRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationNone];

    // If I use some row animation, I can clearly see that the correct row is being animated, it's just not being updated.

}
但标签不会更新。很明显我错过了什么。 这两个视图都是模态视图控制器

这是我的手机结构:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [firstTableView dequeueReusableCellWithIdentifier:CellIdentifier];

    UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(150.0, 15.0, 120.0, 17.0)];
    myLabel.backgroundColor = [UIColor clearColor];
    myLabel.font = [UIFont systemFontOfSize:14];
    myLabel.textAlignment = UITextAlignmentLeft;

    static NSString* kConstants[] = {kOption0,kOption1,kOption2,kOption3,kOption4,kOption5,kOption6,kOption7,kOption8,kOption9,kOption10,nil};

    if (cell == nil) {

        cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

        if (indexPath.section == 2) {
            [cell addSubview:myLabel];
        }   
    }

    switch (indexPath.section) {        
        case 0: 
            // … deal with a bunch of UISwitches        
            break;  
        case 1:
            // … deal with section 1 stuff
            break;
        case 2: 
        {
            NSLog(@"Verify that intType has in fact been changed here: %i, %@",intType, kConstants[intType]);

            // Even though intType and the constant string reflects the correct (updated) values when returning from secondTableView, myLabel.text does not change, ie: it's correct one line above, but not correct one line below. The myLabel.text is just not updating to the new value.

            myLabel.text = kConstants[intType];

            cell.textLabel.text = @"Choose Some Value:";
            cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
        }
            break;
        case 3:     
            // … deal with section 3 stuff
            break;
    }
    [myLabel release];
    return cell;
}

您可以使用reloadRowsAtIndexPaths重新加载特定行,避免重新加载整个表


至于显示字符串值的标签,您能发布代码以便我们查看吗?

我终于发现了问题:当您重新加载单元格时,
(cell==nil)
将为false,因为单元格已经存在

此外,即使
(cell==nil)
为真,您也在添加一个新的子视图,而不是修改现有的子视图——这不仅是内存管理问题,还通过将标签相互重叠使文本无法读取

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    static NSString* kConstants[] = {kOption0,kOption1,kOption2,kOption3,kOption4,kOption5,kOption6,kOption7,kOption8,kOption9,kOption10,nil};

    if (cell == nil) {

        cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

        UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(150.0, 15.0, 120.0, 17.0)];
        myLabel.backgroundColor = [UIColor clearColor];
        myLabel.font = [UIFont systemFontOfSize:14];
        myLabel.textAlignment = UITextAlignmentLeft;
        myLabel.tag = 1;
        myLabel.text = kConstants[intType];

        [cell addSubview:myLabel];
        [myLabel release];

        cell.textLabel.text = @"Label";
        cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
    } else {
        UILabel *myLabel = (UILabel *)[cell viewWithTag:1];
        myLabel.text = kConstants[intType];
    }
    return cell;
}

对于将来偶然发现这一点的人,我在这里发布了我的问题的完整解决方案,特别感谢Antal向我展示了表构造中的主要错误

通常,使用ViewWillAspect重新加载表是个坏主意,因为它会导致表或表的部分加载两次。正确的方法是使用第二个视图控制器的委托方法,我在这里已经完成了

我正在发布两个视图控制器的相关部分。两者都设置为UViewController,而不是UITableViewController。两者都是模态视图

我希望有人觉得这有用

//    
//  FirstViewController.h
//

#import <UIKit/UIKit.h>
#import "SecondViewController.h"

@interface FirstViewController : UIViewController 
<SecondViewControllerDelegate, UITableViewDataSource, UITableViewDelegate>
{
    UITableView  *firstTableView;
    NSArray      *myArray;
}

@property (nonatomic, retain) IBOutlet UITableView *firstTableView;
@property (nonatomic, assign) NSArray *myArray;

- (void) didSelectOptions:(NSInteger *)intOptionType;
- (void) didCancelOptions;

@end


//
//  FirstViewController.m
//

#import "FirstViewController.h"
#import "Constants.h"

@implementation FirstViewController

@synthesize firstTableView;
@synthesize myArray;

- (void) viewDidLoad {

    // Load the array that contains the option names, in this case, constants stored in Constants.h

    myArray = [[NSArray alloc] initWithObjects:kStoredRowName0, kStoredRowName1, kStoredRowName2, nil];

}

// do everything else to deal with the first view . . .

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    // Use the indexPath.section as the identifier since objects in each section share unique construction, ie: switches, etc.

    NSString *identifier = [NSString stringWithFormat: @"%d", [indexPath indexAtPosition: 0]];

    // In this example I'm storing the important integer value in NSUserDefaults as kStoredConstant

    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

    UITableViewCell *cell = [firstTableView dequeueReusableCellWithIdentifier:identifier];

    if (cell == nil) {

        cell = [[[UITableViewCell alloc]
                initWithStyle: UITableViewCellStyleDefault
                reuseIdentifier:identifier]
                autorelease];

        switch (indexPath.section) {
        case 0:                     // OnOff Controls using UISwitch
            NSLog(@"Section 0");
            // set up switches …
            break;
        case 1:                     // Segmented Controls using UISegmentedControl
            NSLog(@"Section 1");
            // set up segmented controls …
            break;
        case 2:                     // Label that will be selected from SecondViewContoller
            NSLog(@"Section 2");
            // set up label
            UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(150.0, 15.0, 120.0, 17.0)];
                myLabel.backgroundColor = [UIColor clearColor];
                myLabel.font = [UIFont systemFontOfSize:14];
                myLabel.textColor = [UIColor colorWithRed:0.25 green:0.0 blue:0.0 alpha:1.0];
                myLabel.textAlignment = UITextAlignmentLeft;
                myLabel.tag = indexPath.section;
                myLabel.text = [myArray objectAtIndex:[userDefaults integerForKey:kStoredConstant]];

                [cell addSubview:myLabel];
                [myLabel release];

            cell.textLabel.text = @"Choose A Value:";
            cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
            break;
        }

    } else {

        switch (indexPath.section) {
        case 0:                     // OnOff Controls using UISwitch
            NSLog(@"Section 0");
            break;
        case 1:                     // Segmented Controls using UISegmentedControl
            NSLog(@"Section 1");
            break;
        case 2:                     // Label that will be selected from SecondViewContoller
            {
            NSLog(@"Section 2");
            UILabel *myLabel = (UILabel *)[cell viewWithTag:indexPath.section];
            myLabel.text = [myArray objectAtIndex:[userDefaults integerForKey:kStoredConstant]];
            }
            break;
        }

    }

    // Format the cell label properties for all cells

    cell.textLabel.backgroundColor = [UIColor clearColor];
    cell.textLabel.font = [UIFont systemFontOfSize:14];
    cell.textLabel.textColor = [UIColor colorWithRed:0.25 green:0.0 blue:0.0 alpha:1.0];
    cell.textLabel.highlightedTextColor = [UIColor colorWithRed:1.0 green:1.0 blue:0.9 alpha:1.0];

    return cell;

}

- (void) tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {

    // Un-highlight the selected cell

    [firstTableView deselectRowAtIndexPath:indexPath animated:YES];

    switch (indexPath.section) {
    case 0:                     // Deal with changes in UISwitch Controls
        NSLog(@"Section 0");
        break;
    case 1:                     // Deal with changes in Segmented Controls
        NSLog(@"Section 1");
        break;
    case 2:                     // Launch the SecondViewContoller to select a value
        {
        SecondViewController *secondViewController = [[SecondViewController alloc] init];
        secondViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
        secondViewController.secondViewControllerDelegate = self;
        [self presentModalViewController:secondViewController animated:YES];
        [secondViewController release];
        }
        break;
    }

}

#pragma mark -
#pragma mark SecondViewControllerDelegate

- (void) didSelectOptions:(NSInteger *)intOptionType {

    // User selected a row in secondTableView on SecondViewController, store it in NSUserDefaults

    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    [userDefaults setInteger:(int)intOptionType forKey:kStoredConstant];
    [userDefaults synchronize];

    // Reload only the row in firstTableView that has been changed, in this case, row 0 in section 2
    [self.firstTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:2]]withRowAnimation:UITableViewRowAnimationNone];

    [self dismissModalViewControllerAnimated:YES];

}

- (void) didCancelOptions {

    // User didn't select a row, instead clicked a done or cancel button on SecondViewController

    [self dismissModalViewControllerAnimated:YES];

}

// Make sure and release Array and Table


//
//  SecondViewController.h
//

#import <UIKit/UIKit.h>

@protocol SecondViewControllerDelegate <NSObject>
    - (void) didCancelOptions;
    - (void) didSelectOptions:(NSInteger *)optionType;
@end

@interface SecondViewController : UIViewController
    <UITableViewDataSource, UITableViewDelegate>
{
    NSArray             *myArray;
    UITableView         *secondTableView;

    id secondViewControllerDelegate;
}

@property (nonatomic, retain) NSArray *myArray;
@property (nonatomic, retain) IBOutlet UITableView *secondTableView;
@property (nonatomic, assign) id<SecondViewControllerDelegate> secondViewControllerDelegate;

- (IBAction) doneViewingOptions:(id)sender;    // This is wired to a Cancel or a Done Button

@end


//
//  SecondViewController.m
//

#import "SecondViewController.h"
#import "Constants.h"

@implementation SecondViewController

@synthesize secondViewControllerDelegate;
@synthesize myArray;
@synthesize secondTableView;

- (void) viewDidLoad {

    // Load the array that contains the option names, in this case, constants stored in Constants.h

    myArray = [[NSArray alloc] initWithObjects:kStoredRowName0, kStoredRowName1, kStoredRowName2, nil];

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    // Build a default table. This one is simple so the following is the only important part:

    cell.textLabel.text = [myArray objectAtIndex:indexPath.row];

}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {  

    // Return the changed row value to the FirstViewController using secondViewControllerDelegate

    [self.secondViewControllerDelegate didSelectOptions:(NSInteger *)indexPath.row];

}

- (IBAction) doneViewingOptions:(id)sender {

    // User didn't select a row, just clicked Done or Cancel button

    [self.secondViewControllerDelegate didCancelOptions];

}

// Make sure and release Array and Table
//
//FirstViewController.h
//
#进口
#导入“SecondViewController.h”
@界面FirstViewController:UIViewController
{
UITableView*第一个TableView;
NSArray*myArray;
}
@属性(非原子,保留)IBUITableView*firstTableView;
@属性(非原子,赋值)NSArray*myArray;
-(void)didSelectOptions:(NSInteger*)输入optionType;
-(无效)选择权;
@结束
//
//FirstViewController.m
//
#导入“FirstViewController.h”
#导入“Constants.h”
@FirstViewController的实现
@综合第一视图;
@合成myArray;
-(无效)viewDidLoad{
//加载包含选项名的数组,在本例中为存储在constants.h中的常量
myArray=[[NSArray alloc]initWithObjects:kstoreDivergame0,kstoreDivergame1,kstoreDivergame2,nil];
}
//做所有其他事情来处理第一个视图。
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath{
//使用indexPath.section作为标识符,因为每个节中的对象共享唯一的结构,例如:开关等。
NSString*标识符=[NSString stringWithFormat:@“%d”,[indexPath indexAtPosition:0]];
//在本例中,我将NSUserDefaults中的重要整数值存储为kStoredConstant
NSUserDefaults*userDefaults=[NSUserDefaults standardUserDefaults];
UITableViewCell*单元格=[firstTableView dequeueReusableCellWithIdentifier:identifier];
如果(单元格==nil){
单元格=[[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:标识符]
自动释放];
开关(indexPath.section){
案例0://使用UISwitch关闭控件
NSLog(“第0节”);
//设置交换机…
打破
案例1://使用UISegmentedControl的分段控件
NSLog(“第1节”);
//设置分段控件…
打破
案例2://将从SecondViewContoller中选择的标签
NSLog(“第2节”);
//设置标签
UILabel*myLabel=[[UILabel alloc]initWithFrame:CGRectMake(150.0,15.0,120.0,17.0)];
myLabel.backgroundColor=[UIColor clearColor];
myLabel.font=[UIFont systemFontOfSize:14];
myLabel.textColor=[UIColor colorWithRed:0.25绿色:0.0蓝色:0.0 alpha:1.0];
myLabel.textAlignment=UITextAlignmentLeft;
myLabel.tag=indexPath.section;
myLabel.text=[myArray objectAtIndex:[userDefaults IntegerWorkey:kStoredConstant]];
[单元格添加子视图:myLabel];
[myLabel释放];
cell.textlab.text=@“选择一个值:”;
cell.accessoryType=UITableViewCellAccessoryDetailDisclosure按钮;
打破
}
}否则{
开关(indexPath.section){
案例0://使用UISwitch关闭控件
NSLog(“第0节”);
打破
案例1://使用UISegmentedControl的分段控件
NSLog(“第1节”);
打破
案例2://将从SecondViewContoller中选择的标签
{
NSLog(“第2节”);
UILabel*myLabel=(UILabel*)[cell viewWithTag:indexPath.section];
myLabel.text=[myArray objectAtIndex:[userDefaults IntegerWorkey:kStoredConstant]];
}
打破
}
}
//格式化所有单元格的单元格标签属性
cell.textLabel.backgroundColor=[UIColor clearColor];
cell.textlab.font=[UIFont systemFontOfSize:14];
cell.textlab.textColor=[UIColor colorWithRed:0.25绿色:0.0蓝色:0.0 alpha:1.0];
cell.textlab.highlightedTextColor=[UIColor COLOR WITHRED:1.0绿色:1.0蓝色:0.9阿尔法:1.0];
返回单元;
}
-(void)tableView:(UITableView*)tableView访问按钮以indexPath:(NSIndexPath*)indexPath显示{
//取消高亮显示所选单元格
[firstTableView取消选择行]