我有一个简单的viewController。 View控制器使用动画。如果我正在显示列表,它将动画显示。那时它也会改变指向地图的按钮而不是指向列表。
因此,通过按住相同的按钮(实际上它是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秒。用户不会喜欢它,即使这是为了他们自己的利益。
所以基本上我必须快速启用重新启用按钮,而不是等到应用程序结束。
但是如何做到这一点仍然可以构建一个能够承受用户快速点击的强大应用程序?
我认为如果有人能够解释何时“真正的”过渡完成,那将会有所帮助。我的意思是从旧的东西的superview实际删除并添加到subview新的东西。动画只是一部“真正改变过渡或视图结构的”电影吗?
答案 0 :(得分:5)
在动画持续时间内,将按钮上的userInteractionEnabled
设置为NO。这会禁用该按钮,但不会更改其外观或增加操作方法的复杂性。
答案 1 :(得分: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);
}
答案 2 :(得分:1)
不是实际启用或禁用按钮,而是将内部布尔变量设置为true或false。然后按下按钮时执行的代码将检查该变量以决定是否忽略按钮按钮或实际执行某些操作。
答案 3 :(得分:-1)
您也可以使用这些代码
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
[[UIApplication sharedApplication] endIgnoringInteractionEvents];
当动画开始时,你可以在完成这个动画后完成