UITableView 拒绝去 detailViewController
Posted
技术标签:
【中文标题】UITableView 拒绝去 detailViewController【英文标题】:UITableView refusing to go to detailViewController 【发布时间】:2012-11-03 04:44:10 【问题描述】:编辑:此问题已移至Getting an error from Xcode that is not on the internet related to index path,因为此问题已修复但出现新错误。
我已经在这里待了 4 天了!我在日志中没有收到任何错误,但是每当我单击填充有从 mysql 下载的动态数组的单元格时,它都不会转换。有趣的是,我没有从 prepareForSegue 中的自我放置的 nslog 中得到任何回应......
ViewController.h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
@interface ViewController : UIViewController<UITableViewDataSource,
CLLocationManagerDelegate,NSXMLParserDelegate, UISearchBarDelegate>
IBOutlet UISearchBar *searchBar;
IBOutlet UITableView *tableView;
IBOutlet UILabel *Label;
CLLocationManager *locationManager;
NSMutableArray *coolarray;
float latitude;
float longitude;
@property (nonatomic, retain) CLLocationManager *locationManager;
@end
我已经排除了已解析的 xml 下载数据,但将 nsarray 的值留在了我的实现文件中
#import "ViewController.h"
#import "DetailViewController.h"
#import "Player.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
- (void)dealloc
[super dealloc];
[self.locationManager release];
if ( coolarray )
[coolarray release];
- (void)viewDidLoad
[super viewDidLoad];
coolarray = NULL;
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.delegate = self;
[self.locationManager startUpdatingLocation];
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
return YES;
// Table data delegate
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
if ( coolarray != NULL )
return [coolarray count];
return 0;
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
Player *cell = [tableView dequeueReusableCellWithIdentifier:@"Player"];
if (cell == nil)
cell = [[[Player alloc] initWithFrame:CGRectZero reuseIdentifier:@"Player"] autorelease];
NSDictionary *itemAtIndex = (NSDictionary *)[coolarray objectAtIndex:indexPath.row];
UILabel *nameLabel =[cell textLabel];
[nameLabel setText:[itemAtIndex objectForKey:@"name"]];
return cell;
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
Player *cell = [tableView dequeueReusableCellWithIdentifier:@"Player"];
if (cell == nil)
cell = [[[Player alloc] initWithFrame:CGRectZero reuseIdentifier:@"Player"] autorelease];
NSDictionary *itemAtIndex = (NSDictionary *)[coolarray objectAtIndex:indexPath.row];
UILabel *nameLabel =[cell textLabel];
[nameLabel setText:[itemAtIndex objectForKey:@"name"]];
return cell;
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
NSString *selectedLang = [coolarray objectAtIndex:indexPath.row];
DetailViewController *myDetViewCont = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:[NSBundle mainBundle]];
myDetViewCont.myDogLang = selectedLang;
[self performSegueWithIdentifier:@"showDogDetail" sender:nil];
[myDetViewCont release];
myDetViewCont = nil;
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
if ([[segue identifier] isEqualToString:@"showDogDetail"])
DetailViewController *detailViewController =
[segue destinationViewController];
NSIndexPath *indexPath = [self.tableView
indexPathForSelectedRow];
NSString *dogLang = [self.coolarray objectAtIndex:indexPath.row];
detailViewController.myDogLang = dogLang;
@end
DetailViewController.h
#import <UIKit/UIKit.h>
@interface DetailViewController : UIViewController
IBOutlet UILabel *myLabel;
NSString *myDogLang;
@property (nonatomic, retain) IBOutlet UILabel *myLabel;
@property (nonatomic, retain) NSString *myDogLang;
@end
DetailViewController.m
#import "DetailViewController.h"
@interface DetailViewController ()
@end
@implementation DetailViewController
@synthesize myLabel;
@synthesize myDogLang;
- (void)viewDidLoad
[super viewDidLoad];
myLabel.text = myDogLang;
self.myLabel.text = [self.myLabel objectAtIndex:0];
- (void)dealloc
[myLabel release];
[myDogLang release];
[super dealloc];
我还添加了一张图片来显示我的连接:
【问题讨论】:
这项工作“myLabel = [[NSArray alloc] ..” myLabel 似乎是 UILabel 并且您正在分配给 NSArray。你能检查一下吗? 你实现tableView:didSelectRowAtIndexPath:
了吗?应该如何调用 segue?
对不起。不小心在我的问题中遗漏了那部分。我已经用 didSelectRowAtIndexPath 更新了这个问题
您的故事板中是否真的有一个带有该标识符的segue?您似乎正在使用 NIB。
是的。我愿意。我正在使用故事板,并且我有一个故事板过渡“showDogDetail”。我应该调用什么来代替 initWithNibName 来反映情节提要?
【参考方案1】:
看起来您在这里混合和匹配了几种不同的样式...我建议简化您的代码:
1) 删除表和详细视图之间的当前segue。通过按住控制键并从原型单元格(我假设这是一个原型表)拖动到目标视图来创建一个新的。不要忘记将标识符命名为与您在 prepareForSegue 代码中使用的名称相同的名称)。此外,如果您将表视图控制器嵌入到导航控制器中(这是通常在可导航表视图上所期望的),则 segue 的样式应为“推送”。否则,样式应该是“模态”(不过,根据您应用的可用性,您可能需要重新考虑这种方法)。
2) Player 类发生了什么?这是一个扩展 UITableViewCell 的类吗?当您单击情节提要中的原型单元格时,身份检查器中列出了什么类?是 Player 还是 UITableViewCell?属性检查器中单元格的标识符是什么?它是 Player 还是空白(给定您的代码,它需要是“Player”)?尝试至少暂时将 Player 课程排除在外。保持单元格的标识符为Player
,但在身份检查器中,将原型单元格的自定义类设置为UITableViewCell
。将您的 tableView:cellForRowAtIndexPath:
方法更改为:
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Player"];
NSDictionary *itemAtIndex = (NSDictionary *)[self.coolarray objectAtIndex:indexPath.row];
cell.textLabel.text = [itemAtIndex objectForKey:@"name"];
return cell;
另外作为旁注,您在此方法中表明coolarray 的成员是NSDictionary 类型。在prepareForSegue 中,您将coolarray 的成员视为NSStrings。不能两者兼有。
3) 摆脱tableView:didSelectRowAtIndexPath:
方法。这个很重要。这里发生了两种相互竞争的 segues 方法。在情节提要和此方法中设置的一个。现在编写代码的方式,单击单元格将调用 prepareForSegue -> didSelect -> prepareForSegue。您在此处尝试执行的所有操作都可以在 prepareForSegue:
方法中完成(请参阅下一步)。
4) 将您的 prepareForSegue: 方法更改为如下所示(您甚至可以摆脱“if”语句,因为您现在只有一个 segue):
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
if ([[segue identifier] isEqualToString:@"showDogDetail"])
DetailViewController *detailViewController =
[segue destinationViewController];
NSIndexPath *indexPath = [self.tableView
indexPathForSelectedRow];
NSString *dogLang = [self.coolarray objectAtIndex:indexPath.row];
// or if the array contains NSDictionaries, change the previous line to:
// NSString *dogLang = [[self.coolarray objectAtIndex:indexPath.row] objectForKey:@"name"];
detailViewController.myDogLang = dogLang;
5) 您的 DetailViewController 的 viewDidLoad 方法正在用一些错误代码覆盖标签文本(UILabel 不是数组)。将代码更改为:
- (void)viewDidLoad
[super viewDidLoad];
self.myLabel.text = self.myDogLang;
鉴于我上面提到的一些概念性问题,我强烈建议阅读Apple's Table View Programming Guide。它将帮助您理清生命周期和流程。
【讨论】:
我像你说的那样放了一个 nslog,但我都没有得到任何回应。我用放置它们的位置更新了我的代码。 啊。我收到错误消息(使用未声明的标识符索引路径。您对我如何去做有什么建议吗? 将myIndexPath
的位置更改为indexPath
(我已经更新了上面的代码)。
好吧,我仍然没有从日志中得到任何响应,而且转换也不起作用。不过谢谢。我将上传头文件和更多的实现,以防万一我在某处遗漏了一步。
确保在 NSLog 语句中将 @ 符号放在字符串之前。您在发布的代码中忘记了这一点: NSLog(@"test");【参考方案2】:
1- 你应该选择你想使用的方法:在情节提要内使用连接或以编程方式加载的细节控制器(使用 didSelectRowAtIndexPath)。现在你正在做两件事:不好。尝试评论您所有的 didSelectRowAtIndexPath 代码并仅使用情节提要。 此外,在您的 didSelectRowAtIndexPath 中,您正在从笔尖加载详细信息 vc ???哪个笔尖?你没有笔尖,你有一个故事板! (您可以以编程方式从情节提要中加载内容,但代码不同)
2- 如果您使用 Push 进行转场,您的故事板中必须有一个 UINavigationController。放置导航控制器,当您将其放置在情节提要中时,它附带了一个 UITableViewController。删除此 UITV 并附加您的。 将单元重新连接到详细控制器并记住为连接提供标识符名称,确保连接从单元开始。 我不确定你是否需要 UINavigationController 即使是模态 segue。
试着告诉我
【讨论】:
好的,我已经完成了所有#2。对于#1,如果我可以在情节提要中直观地传输我的数组coolarray,我会更喜欢这种方式。但是,我愿意在情节提要中以编程方式进行。问题是,我以前从来没有用动态单元格做过这个,所以我会非常感谢任何链接或示例!我已经搜索了互联网,但似乎没有任何东西适合我的情况...... @user1776234 您的代码需要更多的修复,而不仅仅是切换到 UINavigationController。请仔细阅读我上面写的内容... 所以,我做了很多调整。我现在可以让它在用户点击时移动。但是当我希望它显示数组时,它会因不在互联网上的错误而崩溃。这是新问题的链接:***.com/questions/13212906/…以上是关于UITableView 拒绝去 detailViewController的主要内容,如果未能解决你的问题,请参考以下文章