シンプルなviewControllerがあります。ビュー コントローラはアニメーションを使用します。リストを表示している場合は、マップにアニメーション化されます。その際、マップをポイントするボタンもリストをポイントするように変更します。
したがって、同じボタン (実際には 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 つのコントローラー ビューが同じサブビューを持っていることです。関数の最後で遷移がまだ完了していないようです。古いView Controllerは実際には削除されていません。
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;
}
}
クリックが速すぎると、次のメッセージが表示されました。の外観トランジションの開始/終了の不均衡な呼び出し。
その後、アプリは無効な状態になります。
この状況を改善する 1 つの方法は、アニメーションが終了するまでボタンを「無効」にすることです。
-(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;
}
これはうまくいきます。
私のパートナーはそれが好きではありません。これは、無効化されたボタンがわずか .3 秒であっても見苦しく見えるためです。それが自分の利益のためであっても、ユーザーはそれを好まないでしょう。
したがって、基本的には、アプリケーションが終了するまで待つのではなく、ボタンをすばやく再度有効にする必要があります。
しかし、それを行いながら、ユーザーの素早いクリックに耐えられる堅牢なアプリケーションを作成するにはどうすればよいでしょうか?
「実際の」移行がいつ完了したかを誰かが説明してくれると助かると思います。古いもののスーパービューから実際に削除し、新しいもののサブビューに追加することを意味します。アニメーションは、トランジションやビュー構造を実際に変更しない単なる「映画」ですか?