从子视图推送新的视图控制器
Posted
技术标签:
【中文标题】从子视图推送新的视图控制器【英文标题】:Push New View Controller From Subview 【发布时间】:2014-05-05 18:26:10 【问题描述】:我有一个 UITableViewController 作为我的 UIViewController 的子视图。表格视图是从 RSS 提要填充的,并且工作正常。 I'm trying to push a webviewcontroller onto my main navigation stack when a row in the subview is selected but I'm not sure how to get it to work.我知道如果我单独使用 UITableViewController 而不是子视图,我当前的代码会正常工作。
这是我的代码:
- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.title = @"Home";
GRSNewsViewController *newsView = [[GRSNewsViewController alloc]init];
[self addChildViewController:newsView];
[self.view addSubview:newsView.view];
UITableViewController .h:
#import <Foundation/Foundation.h>
@class RSSChannel;
@class WebViewController;
@interface GRSNewsViewController : UITableViewController <NSXMLParserDelegate>
NSURLConnection *connection;
NSMutableData *xmlData;
RSSChannel *channel;
@property (nonatomic, strong)WebViewController *webViewController;
- (void)fetchEntries;
@end
我的 UITableViewController .m:
#import "GRSNewsViewController.h"
#import "RSSChannel.h"
#import "RSSItem.h"
#import "WebViewController.h"
#import "GRSHomeViewController.h"
@interface GRSNewsViewController ()
@end
@implementation GRSNewsViewController
@synthesize webViewController;
- (void)viewDidLoad
[super viewDidLoad];
self.tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 69, 320, 173) style:UITableViewStylePlain];
self.tableView.backgroundColor = [UIColor clearColor];
[self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];
[self.tableView setSeparatorColor:[UIColor whiteColor]];
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
NSLog(@"%@ found a %@ element", self, elementName);
if ([elementName isEqual:@"channel"])
channel = [[RSSChannel alloc]init];
[channel setParentParserDelegate:self];
[parser setDelegate:channel];
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
return [[channel items]count];
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
return 50;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];
if (cell == nil)
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"UITableViewCell"];
cell.textLabel.font = [UIFont systemFontOfSize:16.0];
RSSItem *item = [[channel items]objectAtIndex:[indexPath row]];
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ssZ"];
NSDate *pubDate = [formatter dateFromString:[item date]];
[formatter setDateStyle:NSDateFormatterMediumStyle];
NSString *dateString = [formatter stringFromDate:pubDate];
[[cell textLabel]setText:[item title]];
[[cell detailTextLabel]setText:dateString];
cell.backgroundColor = [UIColor clearColor];
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.textLabel.textColor = [UIColor whiteColor];
cell.detailTextLabel.backgroundColor = [UIColor clearColor];
cell.detailTextLabel.textColor = [UIColor whiteColor];
return cell;
- (void)fetchEntries
xmlData = [[NSMutableData alloc]init];
NSURL *url = [NSURL URLWithString:@"http://onmyhonorband.com/rss"];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
connection = [[NSURLConnection alloc]initWithRequest:req delegate:self startImmediately:YES];
- (id)initWithStyle:(UITableViewStyle)style
self = [super initWithStyle:style];
if (self)
[self fetchEntries];
return self;
- (void)connection:(NSURLConnection *)conn didReceiveData:(NSData *)data
[xmlData appendData:data];
- (void)connectionDidFinishLoading:(NSURLConnection *)conn
NSXMLParser *parser = [[NSXMLParser alloc]initWithData:xmlData];
[parser setDelegate:self];
[parser parse];
xmlData = nil;
[[self tableView] reloadData];
NSLog(@"%@\n %@\n %@\n", channel, [channel title], [channel infoString]);
- (void)connection:(NSURLConnection *)conn didFailWithError:(NSError *)error
connection = nil;
xmlData = nil;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
[[webViewController webView]loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]];
[self.navigationController pushViewController:webViewController animated:YES];
RSSItem *entry = [[channel items]objectAtIndex:[indexPath row]];
NSURL *url = [NSURL URLWithString:[entry link]];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
[[webViewController webView]loadRequest:req];
webViewController.hackyURL = url;
- (void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
@end
【问题讨论】:
你应该检查 self.navigationController 是否为 nil。您可能应该使用 [self.parentViewController.navigationController push...]。 不相关:您将 subview 称为 childViewController..a subview 是一个 view..而且您正在解析 viewController 中的文件..在架构上不正确。 @rdelmar,这是我在控制台中收到的消息:应用程序试图在目标webViewController
?
初始化不声明,他问你在哪里初始化它。即你在哪里创建 webViewController?将其声明为属性并不是创建它。你不能使用不创建它的东西,即你需要分配它
【参考方案1】:
正如其他人在 cmets 中指出的那样,并且正如您收到的控制台消息所示,您的主要问题是您从未初始化 webViewController
。在表视图控制器的 initWithStyle:
初始化程序中添加如下所示的行。
self.webViewController = [[WebViewController alloc] init];
我发现的其他东西:
在viewDidLoad
中分配/初始化一个新的UITableView
。您不应该这样做,因为您正在覆盖由UITableViewController
基类在loadView
中创建的UITableView
实例。查看my other answer,了解有关视图和视图控制器生命周期的更多信息。
在父视图控制器中您忘记调用didMoveToParentViewController
。您需要在致电addChildViewController
后执行此操作。请阅读UIViewController class reference 中的“实现容器视图控制器”部分了解详细信息。
【讨论】:
【参考方案2】:如果 UIViewController addSubView 是 UITableViewController 的一个视图,你想推入 tableView:didSelectRowAtIndexPath 的方法,你应该检查 self.navigationController 是否为 nil。如果它是 nil,你可能应该使用
[self.parentViewController.navigationController pushViewController:controller animated:YES];
如果self.parentViewController也是nil,有时候,你必须设置一个@property来指出UITableViewController中的parentViewController,比如:
@property (nonatomic, weak) UIViewController *parentVC;
在 UIViewController 中:
UITableViewController *tableViewVC = [[UITableViewController alloc] init];
tableViewVC.parentVC = self;
在 UITableViewController 中,-tableView:didSelectRowAtIndexPath:
[self.parentVC.navigationController pushViewController:controller animated:YES];
当你执行时:
NSLog(@"‼️‼️‼️‼️‼️self.navigationController is%@,\n
self.parentViewController.navigationController is %@,\n
self.parentVC.navigationController is %@",self.navigationController,self.parentViewController.navigationController,self.parentVC.navigationController);
它可以打印为:
‼️‼️‼️‼️‼️self.navigationController is(null),
self.parentViewController.navigationController is (null),
self.parentVC.navigationController is <UINavigationController: 0x7af32ae0>
【讨论】:
以上是关于从子视图推送新的视图控制器的主要内容,如果未能解决你的问题,请参考以下文章