【问题标题】:Using the same pointer to point to different UIViewControllers使用相同的指针指向不同的 UIViewController
【发布时间】:2011-04-14 22:39:38
【问题描述】:

也许我试图以错误的方式解决这个问题......

在我的主视图控制器中,我有三个按钮。 每个按钮都会导致加载不同的 UIViewController 及其 nib。

我使用单一方法来处理按钮触摸:

-(IBAction)touched_menu_button:(id)sender
{
SEL selector;

UIButton *button = (UIButton *)sender;

switch (button.tag) 
{
    case 0:
        selector = @selector(ShowA:finished:context:);
        break;

    case 1:
        selector = @selector(ShowB:finished:context:);
        break;

    case 2:
        selector = @selector(ShowC:finished:context:);
        break;

    default:
        selector = @selector(ShowA:finished:context:);
        break;
}

[self FadeOut:selector];
}

这里发生的情况是,在实际显示新视图之前,我正在运行一个小动画。我使用选择器调用“FadeOut”,该选择器将调用动画完成后将显示适当视图的方法。这工作正常。选择器调用的例程如下所示:

-(void)ShowA:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
    A_ViewController *mvc = [[[A_ViewController alloc] init] autorelease];
    mvc.delegate = self;
    [self presentModalViewController:mvc animated:FALSE];
}

这也很好用。

我想做的是将它简化为由选择器调用的单个方法,并将所有冗余代码放在我的“touched_menu_button”方法中。回调函数如下所示:

-(void)ShowNewView:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
    [self presentModalViewController:mvc animated:FALSE];
}

显然,这需要在“mvc”中传递不同的 UIViewController 子类,具体取决于我要显示的视图。这就是我遇到麻烦的地方。也许是因为我已经连续编程了 12 个小时,而且我精神崩溃了,但我似乎无法弄清楚如何做到这一点。我尝试将类变量定义为 void 、void *、id、UIViewController * 和 UIViewController **。由于某种原因,我似乎无法让它工作。

我应该注意到,许多方法确实有效,但是,当视图被关闭并发生自动释放过程时,它们会遇到麻烦。在我尝试过的所有排列中,我似乎未能将指针的地址传递给 UITableView 子类。我现在唯一能确定的选项真的很丑。

【问题讨论】:

    标签: iphone pointers uiviewcontroller


    【解决方案1】:

    您可以传递类本身,而不是将对象传递给回调。

    -(IBAction)touched_menu_button:(id)sender {
        Class theClass;
    
        UIButton *button = (UIButton *)sender;
    
        switch (button.tag) {
            case 0:
                theClass = [A_ViewController class];
                break;
    
            case 1:
                theClass = [B_ViewController class];
                break;
    
            case 2:
                theClass = [C_ViewController class];
                break;
    
            default:
                theClass = [A_ViewController class];
                break;
        }
    
        [self FadeOut:theClass];
    }
    

    FadeOut: 然后使用类作为动画的上下文信息:

    - (void)FadeOut:(Class)theClass {
        //...
        [UIView beginAnimations:@"FadeOut" context:(void*)theClass];
        //...
        [UIView commitAnimations];
        //...
     }
    

    如果您将上下文用于其他用途,则可以使用变量,因为您似乎正在尝试使用视图控制器对象。然后回调分配给它的类。

    -(void)ShowA:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
        Class theClass = (Class)context; // or get it from a variable if you don't use the context
        // If the view controllers all have a shared superclass which declares the delegate property, you can specify that as the type and use dot notation, but otherwise you will need to call setDelegate:
        UIViewController *mvc = [[[theClass alloc] init] autorelease];
        [mvc setDelegate:self];
        [self presentModalViewController:mvc animated:FALSE];
    }
    

    【讨论】:

    • 不错的方法。我喜欢。除了它搁浅的地方是在同一个地方,我在其他想法上遇到了麻烦 [mvc setDelegate:self];此时编译器认为我们正在与一个没有委托属性的 UIViewController 对话。我开始相信我需要一个超类来涵盖所有各种 UIViewController。我想避免这种情况,因为我有点希望这些 UIViewController 能够独立存在以实现可重用性。如果你愿意的话,只为委托创建一个超类会使其不那么“干净”。
    • @Martin 您可以使用超类或协议,或者将其转换为 id:[(id)mvc setDelegate:self]。 (实际上我最初将其键入为 id,但将其更改为 UIViewController)。由于转换为 id 是最简单的并且不需要任何其他修改,我建议这样做。
    • 按广告宣传。谢谢。
    猜你喜欢
    • 2020-07-03
    • 2020-07-20
    • 2016-10-06
    • 2022-06-30
    • 1970-01-01
    • 1970-01-01
    • 2017-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多