Three20:如何在2个视图之间传递一类对象

时间:2010-10-16 14:10:04

标签: iphone objective-c cocoa three20

我有一个TTableView。此表中的项目映射到URL,因此当我单击某个项目时,将显示另一个视图,其中包含有关此项目的信息。 所有这些信息都是类的属性。那么,我如何构建我的TTableTextItem URL以便将包含信息的类传递给负责显示这些信息的视图?

提前致谢。

4 个答案:

答案 0 :(得分:13)

这样做的一种方法是使用TTURLAction。当用户选择表中的一行(将调用您的didSelectObject(TTTableViewController)方法)时,提取您要传递的对象或对象集,并构建如下所示的TTURLAction:

TTURLAction *action =  [[[TTURLAction actionWithURLPath:@"tt://showUser"] 
    applyQuery:[NSDictionary dictionaryWithObject:user forKey:@"kParameterUser"]]
            applyAnimated:YES];

然后打开动作:

[[TTNavigator navigator] openURLAction:action];

由于此操作而要打开的控制器应该在TTURLMap中注册,并且应该有一个构造函数:

- (id) initWithNavigatorURL:(NSURL*)URL query:(NSDictionary*)query {
    self = [super init];
    if (self != nil) {
        self.user = [query objectForKey:kParameterUser];
    }
    return self;
}

我倾向于在类的类上创建类别,我希望能够打开另一个控制器并显示自己。

答案 1 :(得分:6)

直接使用TTURLAction的一个大问题是,您无法真正将它们与TTTableViewItem一起使用。真正做到这一点的唯一方法是覆盖-didSelectObject:atIndexPath:并使用TTURLAction词典中的所需对象构建自定义query。但这会打破模型和视图控制器的良好分离,并且一旦有多个对象通过就会变得复杂。

而不是这个,我一直在使用一个小类,它自动获取表项的userInfo属性(我设置为我需要的任何属性),并自动将其添加为URL参数。

然后使用它在映射的视图控制器中检索它。

- (id)initWithNavigatorURL:(NSURL *)URL query:(NSDictionary *)query { 
if (self = [self initWithNibName:nil bundle:nil]) {
    id myPassedObject = [query objectForKey:@"__userInfo__"];
    // do the rest of your initlization
}
return self;

}

您可以将其下载为GitHub Gist here。代码也在下面。我们正考虑在某个时候将它合并到主分支中。


TTTableViewDelegate + URLAdditions.h

@interface TTTableViewDelegate(URLAdditions)

@end

TTTableViewDelegate + URLAdditions.m

#import "TTTableViewDelegate+URLAdditions.h"

@implementation TTTableViewDelegate(URLAdditions)

- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
    id<TTTableViewDataSource> dataSource = (id<TTTableViewDataSource>)tableView.dataSource;
    id object = [dataSource tableView:tableView objectForRowAtIndexPath:indexPath];

    // Added section to automatically wrap up any TTTableItem userInfo objects.  If it is a dictionary, it gets sent directly
    // If it is not, it is put in a dictionary and sent as they __userInfo__ key
    if( [object isKindOfClass:[TTTableLinkedItem class]] ) {
        TTTableLinkedItem* item = object;

        if( item.URL && [_controller shouldOpenURL:item.URL] ) {
            // If the TTTableItem has userInfo, wrap it up and send it along to the URL
            if( item.userInfo ) {
                NSDictionary *userInfoDict;

                // If userInfo is a dictionary, pass it along else create a dictionary
                if( [item.userInfo isKindOfClass:[NSDictionary class]] ) {
                    userInfoDict = item.userInfo;
                } else {
                    userInfoDict = [NSDictionary dictionaryWithObject:item.userInfo forKey:@"__userInfo__"];
                }

                [[TTNavigator navigator] openURLAction:[[[TTURLAction actionWithURLPath:item.URL]
                                                         applyQuery:userInfoDict]
                                                        applyAnimated:YES]];
            } else {
                TTOpenURL( item.URL );
            }
        }

        if( [object isKindOfClass:[TTTableButton class]] ) {
            [tableView deselectRowAtIndexPath:indexPath animated:YES];
        }
        else if( [object isKindOfClass:[TTTableMoreButton class]] ) {
            TTTableMoreButton* moreLink = (TTTableMoreButton*)object;
            moreLink.isLoading = YES;
            TTTableMoreButtonCell* cell
            = (TTTableMoreButtonCell*)[tableView cellForRowAtIndexPath:indexPath];
            cell.animating = YES;
            [tableView deselectRowAtIndexPath:indexPath animated:YES];

            if( moreLink.model )
                [moreLink.model load:TTURLRequestCachePolicyDefault more:YES];
            else
                [_controller.model load:TTURLRequestCachePolicyDefault more:YES];
        }
    }

    [_controller didSelectObject:object atIndexPath:indexPath];
}

@end

答案 2 :(得分:0)

我认为the documentation on the official website确实非常清楚地描述了Three20的导航方案。您的问题是任何应用程序的常见任务,Three20为此提供了强大的支持。

答案 3 :(得分:0)

我几乎没有修复这个很棒的代码:) 作为TTTableButton发布的版本条带回调。

更正是:

if( [object isKindOfClass:[TTTableButton class]] ) {
   if (item.delegate && item.selector) {
       [item.delegate performSelector:item.selector withObject:object];
   }
   [tableView deselectRowAtIndexPath:indexPath animated:YES];
}