【问题标题】:How to make sure an action completes before you continue如何在继续之前确保操作完成
【发布时间】:2013-11-21 05:39:02
【问题描述】:

我试图通过调用从另一个方法中关闭一个方法中的 UIView,UIView 可以正常关闭,但要等到当前方法中的所有进程都完成后才能关闭。

我想知道是否有办法强制第一件事先发生(即关闭 UIviews)然后继续当前方法?

这就是我的方法的样子

- (void)selectDeselectAllPressed:(UIButton*)button {
    int id = button.tag;
    [SVProgressHUD showWithStatus:@"Updating" maskType:SVProgressHUDMaskTypeGradient];
    [self displaySelected]; // removes current view so you can load hud will not be behind it

    if (id == 1) {
        [self selectAllD];
    } else if (id == 2) {
        [self deselectAllD];
    } else if (id == 3) {
        [self selectAllI];
    } else if (id == 4) {
        [self deselectAllI];
    }
}

如您所见,当按下按钮时会调用此方法,我希望 displaySelected 方法在调用任何其他方法之前执行它需要执行的操作?

目前,当我调试时会发生什么,这是 displaySelected 方法被称为线程遍历,然后继续执行 if 语句,然后在 if 语句中的方法完成后,再进行 displaySelected 更改......这太奇怪了。

更新

这是我调用的方法,有一个 if 语句检查视图是否为 nil,然后加载它,否则卸载它。在我在视图上的代码点已加载,因此当我从 selectDeselectAllPressed 调用它时,它正在输入 else if 方法的一部分来关闭视图。我已经调试过了,看到线程进入这个点

- (void) displaySelected {

    if (allBackGroundView == nil) {

        // load view

        CGFloat fullHeight = [UIScreen mainScreen].bounds.size.height;
        CGFloat fullWidth = [UIScreen mainScreen].bounds.size.width;

        // draw background
        background = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, fullHeight, fullWidth)];
        background.backgroundColor = [UIColor blackColor];
        background.alpha = 0.6;
        [self.view addSubview:background];

        UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(displaySelectedI)];
        gestureRecognizer.cancelsTouchesInView = NO;
        [background addGestureRecognizer:gestureRecognizer];

        allBackGroundView = [[UIView alloc] initWithFrame:CGRectMake(762.0, 43.0, 250.0, 220.0)];
        allBackGroundView.backgroundColor = [UIColor lightGrayColor];
        allBackGroundView.layer.borderWidth = 0.5;
        allBackGroundView.layer.borderColor = [UIColor darkGrayColor].CGColor;
        [self.view addSubview:allBackGroundView];

        // set labeltitles
        selecteAllDFitLabel = [[UILabel alloc] initWithFrame:CGRectMake(10.0, 18.0, 200.0, 30.0)];
        selecteAllDFitLabel.backgroundColor = [UIColor clearColor];
        selecteAllDFitLabel.font = [UIFont boldSystemFontOfSize:16];
        selecteAllDFitLabel.textColor = [UIColor whiteColor];
        selecteAllDFitLabel.text = @"Select all Dfit:";
        [allBackGroundView addSubview:selecteAllDFitLabel];

        deselecteAllDFitLabel = [[UILabel alloc] initWithFrame:CGRectMake(10.0, 65.0, 200.0, 30.0)];
        deselecteAllDFitLabel.backgroundColor = [UIColor clearColor];
        deselecteAllDFitLabel.font = [UIFont boldSystemFontOfSize:16];
        deselecteAllDFitLabel.textColor = [UIColor whiteColor];
        deselecteAllDFitLabel.text = @"Deselect all Dfit:";
        [allBackGroundView addSubview:deselecteAllDFitLabel];

        selecteAllILabel = [[UILabel alloc] initWithFrame:CGRectMake(10.0, 120.0, 200.0, 30.0)];
        selecteAllILabel.backgroundColor = [UIColor clearColor];
        selecteAllILabel.font = [UIFont boldSystemFontOfSize:16];
        selecteAllILabel.textColor = [UIColor whiteColor];
        selecteAllILabel.text = @"Select all I:";
        [allBackGroundView addSubview:selecteAllILabel];

        deselecteAllILabel = [[UILabel alloc] initWithFrame:CGRectMake(10.0, 170.0, 200.0, 30.0)];
        deselecteAllILabel.backgroundColor = [UIColor clearColor];
        deselecteAllILabel.font = [UIFont boldSystemFontOfSize:16];
        deselecteAllILabel.textColor = [UIColor whiteColor];
        deselecteAllILabel.text = @"Deselect all I:";
        [allBackGroundView addSubview:deselecteAllILabel];

        UIImage* okImage = [UIImage imageNamed:@"OK.png"];
        UIImage* noImage = [UIImage imageNamed:@"No.png"];

        selecteAllDFitButton =[UIButton buttonWithType:UIButtonTypeCustom];
        selecteAllDFitButton.tag = 1; // so I know what action to perform when i call selectDeselectAllPressed
        [selecteAllDFitButton addTarget:self
                       action:@selector(selectDeselectAllPressed:)
             forControlEvents:UIControlEventTouchUpInside];
        selecteAllDFitButton.frame = CGRectMake(200.0, 12.0, 40.0, 40.0);
        [selecteAllDFitButton setImage:okImage forState:UIControlStateNormal];
        [allBackGroundView addSubview:selecteAllDFitButton];

        deselecteAllDFitButton =[UIButton buttonWithType:UIButtonTypeCustom];
        deselecteAllDFitButton.tag = 2;
        [deselecteAllDFitButton addTarget:self
                                   action:@selector(selectDeselectAllPressed:)
                         forControlEvents:UIControlEventTouchUpInside];
        deselecteAllDFitButton.frame = CGRectMake(200.0, 62.0, 40.0, 40.0);
        [deselecteAllDFitButton setImage:noImage forState:UIControlStateNormal];
        [allBackGroundView addSubview:deselecteAllDFitButton];

        selecteAllIButton =[UIButton buttonWithType:UIButtonTypeCustom];
        selecteAllIButton.tag = 3;
        [selecteAllIButton addTarget:self
                                     action:@selector(selectDeselectAllPressed:)
                           forControlEvents:UIControlEventTouchUpInside];
        selecteAllIButton.frame = CGRectMake(200.0, 112.0, 40.0, 40.0);
        [selecteAllIButton setImage:okImage forState:UIControlStateNormal];
        [allBackGroundView addSubview:selecteAllIButton];

        deselecteAllIButton =[UIButton buttonWithType:UIButtonTypeCustom];
        deselecteAllIButton.tag = 4;
        [deselecteAllIButton addTarget:self
                                    action:@selector(selectDeselectAllPressed:)
                          forControlEvents:UIControlEventTouchUpInside];
        deselecteAllIButton.frame = CGRectMake(200.0, 162.0, 40.0, 40.0);
        [deselecteAllIButton setImage:noImage forState:UIControlStateNormal];
        [allBackGroundView addSubview:deselecteAllIButton];


    }
    else {
        [allBackGroundView removeFromSuperview];
        [background removeFromSuperview];
        allBackGroundView = nil;
        background = nil;

    }
}

【问题讨论】:

  • 你在displaySelected里面用过多线程吗?
  • 不,我不知道该怎么做。
  • 那你没问题...你可以从displaySelected 发布代码吗?
  • 您应该实现委托模式并在委托方法中执行逻辑工作。或者你可以使用块。
  • 基于块的 API 更受欢迎,因为它与 UIKit 基于块的动画 API 很好地结合在一起。请参阅我对提案的回答。

标签: ios objective-c methods


【解决方案1】:

您需要创建一个基于块的 API,并将一个块传递给 displaySelected

考虑:

- (void)selectDeselectAllPressed:(UIButton*)button {
    int id = button.tag;
    [SVProgressHUD showWithStatus:@"Updating" maskType:SVProgressHUDMaskTypeGradient];
    [self displaySelectedCompletionBlock: ^ (BOOL completed) {
        if(!completed) { return; }

        if (id == 1) {
            [self selectAllD];
        } else if (id == 2) {
            [self deselectAllD];
        } else if (id == 3) {
            [self selectAllI];
        } else if (id == 4) {
            [self deselectAllI];
        }
    }]; // removes current view so you can load hud will not be behind it
}

displaySelectedCompletionBlock::

- (void)displaySelectedCompletionBlock:(void(^)(BOOL))completionBlock
{
    //Setup animations.
    [UIView animateWithDuration:0.5 animations: ^ { /* Do animations here. */ } completion:[completionBlock copy]];
}

这是一个简化,但应该让您知道如何进行。

【讨论】:

  • 我已经更新了我的代码.. 但是我收到了这个错误 不兼容的块指针类型将“void (^)(BOOL)”发送到“void (^)()”类型的参数
  • - (void)displaySelectedCompletionBlock:(void(^)(BOOL))completionBlock
猜你喜欢
  • 1970-01-01
  • 2019-03-12
  • 1970-01-01
  • 2021-04-24
  • 2019-06-13
  • 1970-01-01
  • 2015-09-16
  • 2020-02-24
  • 1970-01-01
相关资源
最近更新 更多