Iphone 更新原始UITableView中第二个UITableView中的选择
我无法使用第二个UITableView中的设置更新第一个UITableView 用户单击firstTableView中的一行,从而显示secondTableView。当用户选择一行时,secondTableView消失,firstTableView重新出现。但是,数据没有更新 我尝试在firstTableView中使用以下内容: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
- (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取消选择行]