传递数据:不调用委托方法 [英] Passing data back :Delegate method not called

查看:167
本文介绍了传递数据:不调用委托方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个与谷歌文档连接的应用程序,使用oauth 2.0,一旦用户连接,他点击一个到tableView的按钮来显示所有的文档。为此,我正在使用segue并传递数据。现在我想让用户选择一个文档,在其上放置一个复选标记,并返回到viewcontroller传回数据,并显示选定的文档。我读到,为了传递数据,我需要使用协议和委托。我遵循:在视图控制器之间传递数据,但我的问题是我的委托方法是没有被调用。



这是我的故事板,只有2个视图,一个viewcontroller和一个tablaviewvcontroller称为 VistaTableViewController 。 / p>



当用户按下认证按钮时,他使用oauth连接到google文档。当他按下Listar按钮时,会出现VistaTableViewController。



这是VistaTableViewController.h的代码,其中定义了协议:

  #import< UIKit / UIKit.h> 
#importGData.h


@class VistaTableViewController;

@protocol VistaTableViewControllerDelegate< NSObject>
- (void)loqueselecciono:(VistaTableViewController *)控制器didSelectDoc :( NSString *)documento;
@end


@interface VistaTableViewController:UITableViewController< UITableViewDataSource>
{
IBOutlet UITableView * tablalistar;
GDataFeedDocList * mDocListFeed2;
}

@property(nonatomic,weak)id< VistaTableViewControllerDelegate>代表;
@property(nonatomic,strong)NSString * documento;
@property(nonatomic,retain)GDataFeedDocList * mDocListFeed2;

@end

这里是VistaTableViewController.m的代码,我调用代理方法:

  #importVistaTableViewController.h


@implementation VistaTableViewController
{
NSInteger selectedIndex;
}

@synthesize delegate;
@synthesize documento;
@synthesize mDocListFeed2;

- (void)viewDidLoad
{
[super viewDidLoad];

selectedIndex = [[mDocListFeed2 entries] indexOfObject:self.documento];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[mDocListFeed2 entries] count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath :( NSIndexPath *)indexPath
{
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@ tablalistar];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@tablalistar];
}

GDataEntrySpreadsheet * doc = [[mDocListFeed2 entries] objectAtIndex:indexPath.row];

cell.textLabel.text = [[doc title] stringValue];

if(indexPath.row == selectedIndex)
cell.accessoryType = UITableViewCellAccessoryCheckmark;
else
cell.accessoryType = UITableViewCellAccessoryNone;

返回单元格;


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

[tableView deselectRowAtIndexPath:indexPath animated :是];
if(selectedIndex!= NSNotFound)
{
UITableViewCell * cell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:selectedIndex inSection:0]];
cell.accessoryType = UITableViewCellAccessoryNone;
}
selectedIndex = indexPath.row;

UITableViewCell * cell = [tableView cellForRowAtIndexPath:indexPath];

cell.accessoryType = UITableViewCellAccessoryCheckmark;

GDataEntrySpreadsheet * doc = [[mDocListFeed2 entries] objectAtIndex:indexPath.row];

NSString * theDoc = [[doc title] stringValue];

[self.delegate loqueselecciono:self didSelectDoc:theDoc];
}

@end

好吧,现在我只是需要告诉ViewController导入VistaTableViewController并符合其协议。



这里是ViewController.h的代码

  #import< UIKit / UIKit.h> 
#importGTMOAuth2ViewControllerTouch.h
#importGData.h
#importVistaTableViewController.h

@interface ViewController:UIViewController< VistaTableViewControllerDelegate>

- (GDataServiceGoogleDocs *)docsService;
- (void)授权;
- (void)mifetch;
- (IBAction)autenticarse;
- (IBAction)listar:(id)sender;
- (void)ticket:(GDataServiceTicket *)ticket finishedWithFeed:(GDataFeedDocList *)feed error:(NSError *)error;

@property(nonatomic,retain)NSString * accessToken;
@property(nonatomic,retain)GDataFeedDocList * mDocListFeed;
@property(nonatomic,retain)GDataServiceTicket * mDoclistFetchTicket;


@end

然后在Viewcontroller.m中实现代理方法如下:(我只想显示一个提示,显示所选文件的标题)。

  (void)loqueselecciono:(VistaTableViewController *)controller didSelectDoc:(NSString *)documento; 
{
[self.navigationController popViewControllerAnimated:YES];

UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:@doc seleccionado
message:[NSString stringWithFormat:@titulo:%@,documento]
delegate: self
cancelButtonTitle:@Dismiss
otherButtonTitles:nil];

[alertView show];
}

在ViewController.m中,我写了这个,以将self分配给委托

   - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{
//确保故事板中的segue名称与此行相同
if([[segue identifier] isEqualToString:@displaydocs])
{
VistaTableViewController * vistatableview = [[ VistaTableViewController alloc] init];

vistatableview.delegate = self;

vistatableview = [segue.destinationViewController performSelector:@selector(setMDocListFeed2 :) withObject:mDocListFeed];
}
}

好的,所以我得到de tableView显示所有的文件并且用户可以选择一个显示de复选标记,但代理方法未被调用,因此它不返回到viewcontroller视图,也没有数据被传回。



什么是我错过了?谢谢!!

解决方案

写入 VistaTableViewController * vistatableview = [[VistaTableViewController alloc] init]; 你正在创建一个新对象。您真正想要做的是使用 segue.destinationViewController ,它应该是一个 VistaTableViewController 并设置委托给 self



同样,与委托对象不是被推送的对象并处理视图逻辑。



(另外, setMDocListFeed2 不返回一个对象,所以在code> performSelector 相当误导。)


I am working on an app that connects with google docs using oauth 2.0, once the user has connected, He clicks a button that goes to a tableView to show all the documents. For this I am using a segue and passing data forward. Now I want the user to select one document, put a checkmark on it and return to the viewcontroller passing data back and display wich document was selected. I read that for passing data back I needed to use a protocol and a delegate. I followed this: Passing Data between View Controllers but my problem is that my delegate method is not being called.

Here is my storyboard, just 2 views, a viewcontroller and a tablaviewvcontroller called VistaTableViewController.

When the user pushes the authenticate button, He connects with google docs using oauth. When he pushes the "Listar" button the VistaTableViewController appears.

Here is the code of VistaTableViewController.h where a define the protocol:

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


@class VistaTableViewController;

@protocol VistaTableViewControllerDelegate <NSObject>
- (void)loqueselecciono:(VistaTableViewController *)controller didSelectDoc:(NSString *)documento;
@end


@interface VistaTableViewController : UITableViewController <UITableViewDataSource>
{
    IBOutlet UITableView *tablalistar;
    GDataFeedDocList *mDocListFeed2;
}

@property (nonatomic, weak) id <VistaTableViewControllerDelegate> delegate;
@property (nonatomic, strong) NSString *documento;
@property (nonatomic, retain) GDataFeedDocList *mDocListFeed2;

@end

Here is the code of VistaTableViewController.m where I call the delegate method:

#import "VistaTableViewController.h"


@implementation VistaTableViewController
{
    NSInteger selectedIndex;
}

@synthesize delegate;
@synthesize documento;
@synthesize mDocListFeed2;

- (void)viewDidLoad
{
    [super viewDidLoad];

    selectedIndex = [[mDocListFeed2 entries] indexOfObject:self.documento];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [[mDocListFeed2 entries] count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"tablalistar"];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"tablalistar"];
    }

    GDataEntrySpreadsheet *doc = [[mDocListFeed2 entries] objectAtIndex:indexPath.row];

    cell.textLabel.text = [[doc title] stringValue];

    if (indexPath.row == selectedIndex)
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    else
        cell.accessoryType = UITableViewCellAccessoryNone;

    return cell;
}

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

    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    if (selectedIndex != NSNotFound)
    {
        UITableViewCell *cell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:selectedIndex inSection:0]];
        cell.accessoryType = UITableViewCellAccessoryNone;
    }
    selectedIndex = indexPath.row;

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

    cell.accessoryType = UITableViewCellAccessoryCheckmark;

    GDataEntrySpreadsheet *doc = [[mDocListFeed2 entries] objectAtIndex:indexPath.row];

    NSString *theDoc = [[doc title] stringValue];

    [self.delegate loqueselecciono:self didSelectDoc:theDoc];
}

@end

Ok, so now I just need to tell ViewController to import VistaTableViewController and conform to its protocol.

here is the code of ViewController.h

#import <UIKit/UIKit.h>
#import "GTMOAuth2ViewControllerTouch.h"
#import "GData.h"
#import "VistaTableViewController.h"

@interface ViewController : UIViewController <VistaTableViewControllerDelegate>

- (GDataServiceGoogleDocs *)docsService;
- (void)authorize;
- (void) mifetch;
- (IBAction)autenticarse;
- (IBAction)listar:(id)sender;
- (void) ticket: (GDataServiceTicket *) ticket finishedWithFeed: (GDataFeedDocList *) feed error: (NSError *) error;

@property (nonatomic, retain) NSString *accessToken;
@property (nonatomic, retain) GDataFeedDocList *mDocListFeed;
@property (nonatomic, retain) GDataServiceTicket *mDoclistFetchTicket;


@end

Then in Viewcontroller.m I implement the delegate method as follows: (I just want to display an alert showing the title of de document that was selected).

- (void)loqueselecciono:(VistaTableViewController *)controller didSelectDoc:(NSString *)documento;
{
    [self.navigationController popViewControllerAnimated:YES];

    UIAlertView *alertView = [ [UIAlertView alloc] initWithTitle:@"doc seleccionado"
                                                         message:[NSString stringWithFormat:@"titulo: %@", documento]
                                                        delegate:self
                                               cancelButtonTitle:@"Dismiss"
                                               otherButtonTitles:nil];

    [alertView show];
}

and in Viewcontroller.m as well I wrote this to assign self to the delegate.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Make sure your segue name in storyboard is the same as this line
    if ([[segue identifier] isEqualToString:@"displaydocs"])
    {
        VistaTableViewController *vistatableview = [[VistaTableViewController alloc] init];

        vistatableview.delegate = self;

        vistatableview = [segue.destinationViewController performSelector:@selector(setMDocListFeed2:) withObject:mDocListFeed];
    }
}

Ok, so I get de tableView displaying all the documents and the user can select one showing de checkmark but the delegate method is not being called so It does not return to the viewcontroller view and no data is passed back.

What am I missing?? Thanks!!

解决方案

When you write VistaTableViewController *vistatableview = [[VistaTableViewController alloc] init]; you are creating a new object. What you really want to do is use the segue.destinationViewController, which should be a VistaTableViewController and set its delegate to self.

As is, the object with the delegate is not the object being pushed and handling the view logic.

(Also, setMDocListFeed2 doesn't return an object so the assignment on performSelector is rather misleading.)

这篇关于传递数据:不调用委托方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆