无法在外部方法中访问UIView

时间:2011-06-15 00:31:15

标签: objective-c uiview

我是Objective-C的新手,所以我这样做的方式可能很荒谬,但是这里有:

我的iPhone应用程序中有一个登录表单。当用户输入他们的凭据时,他们在右上角点击Done,这会触发IBAction并弹出自定义进度指示器。我已经使用包含名为 showProgressIndicator 的实例方法的类创建了此指标。 showProgressIndicator 创建并返回一个UIView,然后我将其添加到我的视图中:

ProgressIndicatorElement *ProgressIndicator = [[ProgressIndicatorElement alloc] init];
box = [ProgressIndicator showProgressIndicator];
[self.view addSubview:box];

我当然在我的头文件中将box声明为UIView。漂亮的进度指示器弹出,同时我正在做一个幕后的URL请求,完成后,在我的视图控制器中调用名为 receivedServerResponse 的另一个方法。现在,我想要做的是删除进度指示器,这就是我这样做的原因:

- (void)receivedServerResponse {
    [box removeFromSuperview];
}

但根本没有任何事情发生。我没有收到任何错误或警告,代码正在突出显示,就好像一切都运行顺利。我已经尝试在我的IBAction中保留指标,但这也无济于事。

希望你能帮忙!

更新

这是 showProgressIndicator 方法:

- (UIView *)showProgressIndicator {
    box = [[UIView alloc] initWithFrame:CGRectMake(85, 190, 210, 140)];
    box.backgroundColor = [UIColor colorWithRed:0.0 / 255 green:0.0 / 255 blue:0.0 / 255 alpha:.6];
    box.layer.cornerRadius = 8;

    UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    spinner.layer.frame = CGRectMake((box.layer.bounds.size.width - spinner.layer.bounds.size.width)/2, 20, spinner.layer.bounds.size.width, spinner.layer.bounds.size.height);
    [spinner startAnimating];
    [box addSubview:spinner];

    UILabel *titleInBox = [[UILabel alloc] initWithFrame:CGRectMake(0, 65, 150, 20)];
    titleInBox.font = [UIFont boldSystemFontOfSize:16];
    titleInBox.textColor = [UIColor whiteColor];
    titleInBox.textAlignment = UITextAlignmentCenter;
    titleInBox.backgroundColor = [UIColor clearColor];
    titleInBox.text = @"Authorizing...";
    [box addSubview:titleInBox];

    return box;
}

第二次更新:

@Deepak在评论中指出我可能正在运行我的视图控制器的两个不同实例,实际上似乎就是这种情况。在处理上述URL请求的外部类中,我通过执行以下操作返回到视图控制器的 receivedServerResponse 方法:

- (void)requestFinished:(ASIHTTPRequest *)request {
    NSString *responseString = [request responseString];
    SignInViewController *viewController = [[SignInViewController alloc] init];
    [viewController receivedServerResponse];
}

如果没有太过分散(可能太晚了)),ASIHTTPRequest设置为如果你调用一个执行异步URL请求的方法,那么一个名为 requestFinished 的预定义方法(上面)是调用,这就是为什么我必须以这种方式调用我的视图控制器,因为我无法以更简单的方式访问返回的值(我知道)。

5 个答案:

答案 0 :(得分:2)

创建SignInViewController的新实例不是正确的方法。保持assign对象的弱引用(SignInViewController ed属性)似乎是正确的。说你的班级是RequestHandler

@interface RequestHandler: [..] {
}

@property (nonatomic, assign) SignInViewController * signInViewController;

@end

@implementation RequestHandler
@synthesize signInViewController;
[..]
- (void)requestFinished:(ASIHTTPRequest *)request {
    NSString *responseString = [request responseString];
    [signInViewController receivedServerResponse];
}
@end

因此,当您在RequestHandler实例中创建SignInViewController对象时,您可以

RequestHandler * requestHandler = [[RequestHandler alloc] init];
requestHandler.signInViewController = self;
[..]

注意,您还可以查看委派和notifications

答案 1 :(得分:1)

我认为问题的一部分可能与内存管理有关。如果showProgressIndicator没有返回自动释放的对象,请在将其添加为子视图后尝试释放框,如下所示:

[self.view addSubview:box];
[box release];
如果从超级视图中删除box时未解除分配,则

box可能不会消失。

我的另一个建议是,不是按照您的方式执行,创建视图,添加视图,然后尝试删除它,您可能希望在创建登录视图和设置时尝试添加框作为子视图它的hidden属性为YES,然后在必要时取消隐藏。

根据您的更新showProgressIndicator中存在一些内存管理问题。无论何时分配对象,都应该释放它。在这种情况下,在将它们添加为上面提到的子视图后释放所有变量。但是,框应该作为自动释放的对象返回,因为showProgressIndicator不知道何时需要释放它。为此,您应将return box;替换为return [box autorelease];

答案 2 :(得分:0)

当您希望动画停止时,您需要向活动指示器发送stopAnimating消息。没有必要将其从超级视图中删除;相反,只需确保其hidesWhenStopped属性设置为YES

答案 3 :(得分:0)

如何在appDelgate中的窗口上添加框视图?为boxView提供标记,在remove方法中使用标记返回boxView。例如,如果您提供标签99

- (void)receivedServerResponse {
    UIView *box = [window viewWithTag:99];
    [box removeFromSuperview];
}

您也不需要在头文件中声明实例变量。并且您可以在应用程序的任何位置访问进度指示器。

答案 4 :(得分:0)

  

如果没有太过分散(可能太晚了)),ASIHTTPRequest设置为如果你调用一个执行异步URL请求的方法,就会调用一个名为requestFinished(上面)的预定义方法,这就是为什么我'我必须以这种方式调用我的视图控制器,因为我无法以更简单的方式访问返回的值(我知道)。

ASIHTTPRequest调用-requestFinished:在您设置为请求委托的对象上。您应该设计类,以便此委托对象具有对您希望它作用的视图控制器的引用,或者具有一些通知视图控制器采取操作的方法。 最简单的解决方案可能是使控制器成为请求的委托。