質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Swift 2

Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。

Q&A

解決済

1回答

3816閲覧

UIView.animateWithDurationの使い方について

lyzmfeqpxs54

総合スコア237

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Swift 2

Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。

0グッド

0クリップ

投稿2016/06/03 00:17

現在swiftでクイズの作成を行っています。問題文の表示のところで行き詰まっております。下記のようにして問題文の表示を1行目から順に表示させています。次の問題に進む際には下記の問題削除メソッドでラベルを削除し、また1行目からラベルの表示を行っています。次の問題メソッドは回答してから1秒後に呼ばれます。

現状では表示自体は正しく動いてはいるのですが、問題文の表示中に回答を行い次の問題文の表示に移行した場合に前回のラベルが表示されてしまいます。

具体例としまして今の問題文が4行、次の問題が2行とします。
今の問題文が仮に2行目を表示している時に問題の回答を行なったとします。
次の問題メソッドがよばれラベルの削除を行ない、次の問題が表示されるのですが前回の3行目と4行目も続けて表示さてしまいます。

問題文の表示をUIView.animateWithDurationの終了の度に次の行の文を表示するというこの方法はあまりよくないのでしょうか(他に思いつかなかったのですが・・・)。
この方法の場合次の問題がよばれたらUIView.animateWithDurationを停止するようにしたほうがよいのでしょうか。また、停止はどのようにおこなえばよいのでしょうか。UIView.animateWithDurationの停止は調べてみたのですがなかなか出てきませんでした・・・。

長文かつ分かりにくい文章で申し訳ありません。
ご助言をいただければ幸いです。

//問題文を表示するメソッド
func questionDisplay(){

var str = mondaiArray[3].componentsSeparatedByString("/") // mondaiArray[3]には問題文が入っています str += ["","",""] //問題文が1行の場合に空白を作らないように(この方法もよくないと思ってはいるのですが・・・) // 問題文各行の文字数を数える let line1 = str[0].characters.count let line2 = str[1].characters.count let line3 = str[2].characters.count let line4 = str[3].characters.count // Duuble型にキャスト(animateWithDurationに代入するため) let line1CG:Double = Double(line1) let line2CG:Double = Double(line2) let line3CG:Double = Double(line3) let line4CG:Double = Double(line4) // ラベルの作成 幅0のラベル。後で問題文の文字列に対してぴったりの幅のラベルをアニメーション終了とすることで、問題文が1文字目から順に表示されるようにしている。 scWidとscHeiはそれぞれ画面の幅と高さ(screenwidth) let myLabel1: UILabel = UILabel(frame: CGRectMake(scWid*0.18 ,scHei*0.15 ,0 ,scHei*0.08)) let myLabel2: UILabel = UILabel(frame: CGRectMake(scWid*0.18 ,scHei*0.20 ,0 ,scHei*0.08)) let myLabel3: UILabel = UILabel(frame: CGRectMake(scWid*0.18 ,scHei*0.25 ,0 ,scHei*0.08)) let myLabel4: UILabel = UILabel(frame: CGRectMake(scWid*0.18 ,scHei*0.30 ,0 ,scHei*0.08)) // タグ番号の追加 myLabel1.tag = 7 myLabel2.tag = 8 myLabel3.tag = 9 myLabel4.tag = 10 // フォントサイズの指定 myLabel1.font = UIFont.systemFontOfSize(14) myLabel2.font = UIFont.systemFontOfSize(14) myLabel3.font = UIFont.systemFontOfSize(14) myLabel4.font = UIFont.systemFontOfSize(14) // 文字の色を白にする. myLabel1.textColor = UIColor.whiteColor() myLabel2.textColor = UIColor.whiteColor() myLabel3.textColor = UIColor.whiteColor() myLabel4.textColor = UIColor.whiteColor() //テキストの表示 myLabel1.text = str[0] myLabel2.text = str[1] myLabel3.text = str[2] myLabel4.text = str[3] // ViewにLabelを追加. self.view.addSubview(myLabel1) UIView.animateWithDuration(line1CG/15, delay: 0.0, options : UIViewAnimationOptions.CurveLinear, animations: {() -> Void in //ここでは文字数に応じて幅がぴったりラベルを表示しています let myaLabel1_frame: CGSize = CGSizeMake(240, 50) //一旦大まかなサイズを指定 let myaLabel1_text_frame: CGSize = myLabel1.sizeThatFits(myaLabel1_frame) let myaLabel1_text_width: CGFloat = myaLabel1_text_frame.width myLabel1.frame = CGRectMake(self.scWid*0.18 ,self.scHei*0.15 ,myaLabel1_text_width ,self.scHei*0.08) //return }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 1行目の表示が終わったら2行目の表示 self.view.addSubview(myLabel2) UIView.animateWithDuration(line2CG/15, delay: 0.0, options : UIViewAnimationOptions.CurveLinear, animations: {() -> Void in let myaLabel2_frame: CGSize = CGSizeMake(240, 50) let myaLabel2_text_frame: CGSize = myLabel2.sizeThatFits(myaLabel2_frame) let myaLabel2_text_width: CGFloat = myaLabel2_text_frame.width myLabel2.frame = CGRectMake(self.scWid*0.18 ,self.scHei*0.20 ,myaLabel2_text_width ,self.scHei*0.08) //return }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 同じく3行目 self.view.addSubview(myLabel3) UIView.animateWithDuration(line3CG/15, delay: 0.0, options : UIViewAnimationOptions.CurveLinear, animations: {() -> Void in let myaLabel3_frame: CGSize = CGSizeMake(240, 50) let myaLabel3_text_frame: CGSize = myLabel3.sizeThatFits(myaLabel3_frame) let myaLabel3_text_width: CGFloat = myaLabel3_text_frame.width myLabel3.frame = CGRectMake(self.scWid*0.18 ,self.scHei*0.25 ,myaLabel3_text_width ,self.scHei*0.08) //return }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 同じく4行目 self.view.addSubview(myLabel4) UIView.animateWithDuration(line4CG/15, delay: 0.0, options : UIViewAnimationOptions.CurveLinear, animations: {() -> Void in let myaLabel4_frame: CGSize = CGSizeMake(240, 50) let myaLabel4_text_frame: CGSize = myLabel4.sizeThatFits(myaLabel4_frame) let myaLabel4_text_width: CGFloat = myaLabel4_text_frame.width myLabel4.frame = CGRectMake(self.scWid*0.18 ,self.scHei*0.30 ,myaLabel4_text_width ,self.scHei*0.08) //return }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 }) }) }) }) } //次の問題を表示するメソッド func nextProblem(){ labelRemove() // UILabel削除 (以下略)

}
//各種ラベルを削除するメソッド
func labelRemove(){
// self.viewの上に乗っているオブジェクトを順番に取得
for v in self.view.subviews {
// オブジェクトの型がUILabel型で、タグが10番以下のオブジェクトを取得 7〜10:問題表示ラベル
if let v = v as? UILabel where v.tag <= 10 {
// そのオブジェクトを親のviewから取り除く
v.removeFromSuperview()
}
}
}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

アニメーションの停止は、アニメーションしているビューのレイヤーに対してremoveAllAnimations()を呼び出すことでできます。
(参考)
https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CALayer_class/#//apple_ref/occ/instm/CALayer/removeAllAnimations

なお、アニメーション処理が途中でキャンセルされるとアニメーション完了時(completionハンドラ)のfinishedパラメータがfalseで呼び出されます。

提示されたソースコードの修正ポイントを具体的に言うと、
0. labelRemove()関数で v.removeFromSuperView()する直前にv.layer.removeAllAnimations()を入れてアニメーションを削除する。
0. アニメーション処理の各completionハンドラの処理でfinishedパラメータを参照し、finishedがfalseであれば続きのアニメーションを開始しないようにする。

これでうまくいくと思います。

投稿2016/06/04 01:39

TakeOne

総合スコア6299

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lyzmfeqpxs54

2016/06/04 04:32

ご教示いただいた内容で無事解決いたしました!本当にありがとうございます! v.layer.removeAllAnimations()の追加および // アニメーション終了後の処理 if finished == false { return } の追加で解決できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問