2

我有一个简单的视图控制器。视图控制器使用动画。如果我正在显示列表,它将动画到地图。那时它也会将指向地图的按钮改为指向列表。

因此,通过按住同一个按钮(实际上是 2 个不同的按钮,但用户将其视为同一个按钮),用户可以不断地从地图切换到列表,反之亦然。

工作正常。有一些捕捉。

如果用户点击太快怎么办?假设我希望我的应用程序确实被使用,那么罐头或惩罚它们不是一种选择。

这是当前程序:

-(void) transitiontoViewController:(UIViewController *)toViewController duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL))completion1
{


    [self enableButtonWithBool:false];
    UIViewController * fromController = self.last2ViewsInTheContainer.lastObject;
    if (fromController.view.superview!= self.ContainerView)
    {
        return;
    }
    [self transitionFromViewController:fromController toViewController:toViewController duration:duration options:options animations:animations completion:^(BOOL finished) {
        if (completion1 == Nil) //can't execute nil block. can be more elegantly done with [completion1 invoke] if there is such function. Anyway, do nothing if completion1 is nil
        {

        }
        else
        {
            completion1 (finished);
        }
        [self.last2ViewsInTheContainer addObject:toViewController];

        if (self.last2ViewsInTheContainer.count>2)
        {
            [self.last2ViewsInTheContainer removeObjectAtIndex:0];
        }
    }];

    [self enableButtonWithBool:true];
    [self ReloadorRedraw];
}

简单的过渡。我只想在函数的末尾指出 2 个控制器视图具有相同的子视图。在函数结束时,转换似乎尚未完成。旧的视图控制器并没有真正删除,等等。

ReloadorRedraw 的内容如下:

-(void)ReloadorRedraw;
{
    BGCRBadgerStandardViewViewController * listOrMap = nil;
    if ([self.last2ViewsInTheContainer lastObject]==self.filterController)
    {
        [self.changeFilterButton setBackgroundImage:[UIImage imageNamed:filterBarOpenImageString] forState:UIControlStateNormal];
        listOrMap = self.last2ViewsInTheContainer[0];
    }
    else
    {
        [self.changeFilterButton setBackgroundImage:[UIImage imageNamed:filterBarCloseImageString] forState:UIControlStateNormal];
        listOrMap = self.last2ViewsInTheContainer.lastObject;
    }

    if (listOrMap==self.listBusinessViewController)
    {
        self.navigationItem.rightBarButtonItem=self.mapButton;
    }
    else
    {
        self.navigationItem.rightBarButtonItem=self.listButton;
    }
}

如果我点击得太快,我会收到以下消息:不平衡调用开始/结束外观转换。开始/结束外观转换的不平衡调用。

之后应用程序处于无效状态。

补救这种情况的一种方法是“禁用”按钮,直到动画完成。

-(void) transitiontoViewController:(UIViewController *)toViewController duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL))completion1
{


    [self enableButtonWithBool:false];
    UIViewController * fromController = self.last2ViewsInTheContainer.lastObject;
    if (fromController.view.superview!= self.ContainerView)
    {
        return;
    }
    [self transitionFromViewController:fromController toViewController:toViewController duration:duration options:options animations:animations completion:^(BOOL finished) {
        if (completion1 == Nil) //can't execute nil block. can be more elegantly done with [completion1 invoke] if there is such function. Anyway, do nothing if completion1 is nil
        {

        }
        else
        {
            completion1 (finished);
        }
        [self.last2ViewsInTheContainer addObject:toViewController];

        if (self.last2ViewsInTheContainer.count>2)
        {
            [self.last2ViewsInTheContainer removeObjectAtIndex:0];
        }

    [self enableButtonWithBool:true];
    [self ReloadorRedraw];
    }];

}

基本上我在搬家

    [self enableButtonWithBool:true];
    [self ReloadorRedraw];

到完成块。

函数 enableButtonWithBool 就是这个简单的函数:

-(void)enableButtonWithBool: (BOOL) enable
{
    self.mapButton.enabled=enable;
    self.listButton.enabled= enable;
    self.changeFilterButton.enabled =enable;
    self.searchBar.enabled =enable;
}

这很好用。

我的伴侣不喜欢它。那是因为禁用按钮看起来很难看,即使只有 0.3 秒。即使是为了他们自己的利益,用户也不会喜欢它。

所以基本上我必须快速启用重新启用按钮,而不是等到应用程序结束。

但是如何做到这一点,并且仍然制作出能够承受用户快速点击的强大应用程序呢?

我认为如果有人也可以解释“真正的”过渡何时完成,那将有所帮助。我的意思是从旧东西的超级视图中实际删除并添加到新东西的子视图中。动画只是一部不会真正改变过渡或视图结构的“电影”吗?

4

4 回答 4

6

在动画期间将按钮设置userInteractionEnabled为 NO。这会禁用按钮,但不会更改其外观或增加操作方法的复杂性。

于 2012-10-21T14:43:46.083 回答
2

单击按钮后,将其更改为微调器,这是一个视觉指示器,不要一直触摸按钮,并且由于微调器是一个新按钮,它会替换被触摸的按钮,您将不会再点击该按钮,然后当完成代码将微调器更改回您的按钮。

- (void) saveButtonPressed:(id) sender {
//remove keyboard if up
 [[self view] endEditing:YES];

//start a spinner to let user know it is saving
spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[spinner startAnimating];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:spinner];

dispatch_async(appendQueue, ^{
....my code....

您可以在此处或下方结束微调器 dispatch_async(dispatch_get_main_queue(), ^{ self.navigationItem.rightBarButtonItem = sender; });

    [self performSelectorOnMainThread:@selector(doneWithSave:)
                           withObject:sender waitUntilDone:YES];
});
dispatch_release(appendQueue);

}

  • (void) doneWithSave:(id) button { self.navigationItem.rightBarButtonItem = button; [self.navigationController popToRootViewControllerAnimated:TRUE]; }
于 2012-10-21T14:34:12.887 回答
1

无需实际启用或禁用按钮,而是将内部布尔变量设置为 true 或 false。然后按下按钮时执行的代码将检查该变量以决定是忽略按钮按下还是实际执行某些操作。

于 2012-10-21T14:36:29.580 回答
-1

您也可以使用这些代码

[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
[[UIApplication sharedApplication] endIgnoringInteractionEvents];

当动画开始时,您可以在此动画完成后 beginIgnoringInteractionEvents 和 endIgnoringInteractionEvents

于 2014-12-18T06:41:57.607 回答