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

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

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

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

Q&A

解決済

4回答

2326閲覧

【Swift】時間経過で数値を減少させたい

RagnAnet1373

総合スコア69

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

0グッド

0クリップ

投稿2017/04/28 05:19

編集2017/04/28 06:02

###前提・実現したいこと
アプリ作成も少しずつ進んでいますが、
今回もルーレットでのことです。
実現したいのはボタン一つで回転のスタート、ストップを実装しているのですが、
今回ストップをしたときに時間経過とともに回転のスピード(今回の場合1.0)を0.1ずつ減少させていき、ゆっくりと止めたいと思っております
(roulettelayer.speed)

###発生している問題・エラーメッセージ

エラーメッセージは下記のような長文がでました 2017-04-28 14:02:13.524 /*アプリ名*/[9386:893697] -[/*アプリ名*/.RouletteView speedDown:]: unrecognized selector sent to instance 0x7fa5cac0f470 2017-04-28 14:02:13.536 SplitTB[9386:893697] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[/*アプリ名*/.RouletteView speedDown:]: unrecognized selector sent to instance 0x7fa5cac0f470' *** First throw call stack: ( 0 CoreFoundation 0x000000010f162b0b __exceptionPreprocess + 171 1 libobjc.A.dylib 0x000000010ebc7141 objc_exception_throw + 48 2 CoreFoundation 0x000000010f1d2134 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132 3 CoreFoundation 0x000000010f0e9840 ___forwarding___ + 1024 4 CoreFoundation 0x000000010f0e93b8 _CF_forwarding_prep_0 + 120 5 Foundation 0x000000010e726f17 __NSFireTimer + 83 6 CoreFoundation 0x000000010f0f6454 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20 7 CoreFoundation 0x000000010f0f60e3 __CFRunLoopDoTimer + 1011 8 CoreFoundation 0x000000010f0f5caa __CFRunLoopDoTimers + 266 9 CoreFoundation 0x000000010f0ed9ec __CFRunLoopRun + 1916 10 CoreFoundation 0x000000010f0ed016 CFRunLoopRunSpecific + 406 11 GraphicsServices 0x0000000114faaa24 GSEventRunModal + 62 12 UIKit 0x000000010fecd0d4 UIApplicationMain + 159 13 SplitTB 0x000000010e5bc107 main + 55 14 libdyld.dylib 0x000000011320765d start + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException

###該当のソースコード

swift

1 var downSpeed:Double! = 1.0 2 let downval:Double! = 0.1 3 var ans:Double! = 0 4 var t:Double!=0 5 6 func spinStop(_ sender: UIView) 7 { 8 let roulettelayer = sender.layer 9 let pauseTime = roulettelayer.convertTime(CACurrentMediaTime(),from: nil) 10 roulettelayer.speed = 0 11 roulettelayer.timeOffset = pauseTime 12 } 13 14 15//上記コードを 16 17//下記コードのようにしました 18 19 var downSpeed:Double! = 1.0 20 let downval:Double! = 0.1 21 var ans:Double! = 0 22 var t:Double!=0 23 24 func spinStop(_ sender: UIView) 25 { 26 downSpeed = 1.0 27 let roulettelayer = sender.layer 28 let pauseTime = roulettelayer.convertTime(CACurrentMediaTime(),from: nil) 29 Timer.scheduledTimer(timeInterval: 0.05,target:self,selector:Selector(("speedDown:")),userInfo:nil,repeats:true) 30 roulettelayer.speed = Float(ans) 31 roulettelayer.timeOffset = pauseTime 32 } 33 34 func speedDown(sender:Timer) 35 { 36 if(downSpeed != 0) 37 { 38 downSpeed = downSpeed - downval 39 ans = downSpeed 40 } 41 else if(downSpeed <= 0) 42 { 43 sender.invalidate() 44 } 45 } 46

###試したこと
Timer関数というものを調べていろいろなサイトをみたりappleのサイトで見たりして調べながら試行錯誤したのですが、どうしてもうまく理解できず滞ってしまいました・・・。

###補足情報(言語/FW/ツール等のバージョンなど)
Swift3,Xcode8.3です
Timer関数の解釈の仕方やここが一番わかりやすいサイト、などご教授いただければ幸いです・・・。

宜しくお願い致します。

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

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

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

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

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

fuzzball

2017/04/28 05:44

質問のコードはRouletteViewクラス内のコードでしょうか?
fuzzball

2017/04/28 05:51

セレクタの指定の仕方が古いので修正してみて下さい。Selector()ではなく#selector()を使います。
RagnAnet1373

2017/04/28 06:01

>>>質問のコードは...はい、RouletteView内のコードです。引数の情報がコードにないので追加しますね。>>>セレクタの指定...わかりました。探して見ます
RagnAnet1373

2017/04/28 06:24

#selectorを使うとエラーは無くなりました。ただ、この進めて、止めてを連続で何回か繰り返すと早くなったり遅くなったりを繰り返し最終的に完全停止してしまいました。これは引数代入が連続で行われないという状態なのでしょうか?
fuzzball

2017/04/28 07:01 編集

減速処理とタイマー処理を切り離して原因を探った方が良いです。タイマーを使うのではなく、タップするたびに減速するようにして、まずは減速処理が正しく動いているかどうか調べて下さい。
RagnAnet1373

2017/04/28 07:34

回答にて一回スクリプトを書き出します
fuzzball

2017/04/28 07:55

speedDown()はどのように呼び出しているのでしょうか?
RagnAnet1373

2017/04/28 08:03

RouletteController(viewcontroller)クラスからボタンが押されたときにswitch文を使って呼び出しているのですが、1回押すとボタンの機能がローテーションで変わっていくので、現在減少専用のボタンを使用しております。
guest

回答4

0

自己解決

申し訳ございません。仕様を大幅に変更したため今回の質問は締めさせていただきます。

投稿2017/06/02 04:16

RagnAnet1373

総合スコア69

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

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

0

このようにするとなんとかできました
ただ、現状このコードで動かすと
ルーレットが減速する毎に、かくつきながら減速してしまいます・・・。
(たまにルーレットが一気に180度回転したりも・・・)
滑らかに減速するためにはもっと細かく下げるべきなのでしょうか・・・?

swift

1 //一時停止 2 func spinStop(_ sender: UIView) 3 { 4 //downSpeed = 1.0 5 _ = sender.layer 6 if(downSpeed > 0) 7 { 8 //let pauseTime = roulettelayer.convertTime(CACurrentMediaTime(),from: nil) 9 Timer.scheduledTimer(timeInterval: 1,target:self,selector:#selector(self.speedDown),userInfo: nil,repeats:true) 10 //roulettelayer.speed = Float(ans!)/*speedDown(downSpeed,downval)*/ 11 //roulettelayer.timeOffset = pauseTime 12 } 13 } 14 15 func speedDown(sender:Timer)//(_ speed:Double,_ val:Double)->Float 16 { 17// var dSpeed = speed 18// let dVal = val 19 if(downSpeed > 0.05) 20 { 21 self.layer.timeOffset = self.layer.convertTime(CACurrentMediaTime(),from: nil) 22 downSpeed = downSpeed - downval 23 self.layer.speed = Float(downSpeed) 24 //downSpeed = downSpeed - downval 25 //ans = downSpeed 26 } 27 else if(downSpeed <= 0.05) 28 { 29 self.layer.timeOffset = self.layer.convertTime(CACurrentMediaTime(),from: nil) 30 self.layer.speed = 0 31 sender.invalidate() 32 //downSpeed = 1.0 33 } 34 } 35

投稿2017/05/02 01:13

RagnAnet1373

総合スコア69

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

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

0

Timerによって定期的にspeedDown()が呼び出していますが、layerのspeedやtimeOffsetの設定が行われていません。(タップしたときの1回だけしか設定されていない)

speedDown()の中でこれらのプロパティの設定を行って下さい。(この修正で正しく動く保証はありませんが‥)

テストするときは、タイマーの間隔を長めにするといいですよ。(1秒とか)

投稿2017/04/28 08:29

fuzzball

総合スコア16731

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

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

RagnAnet1373

2017/04/28 08:38

わかりました。 とりあえず修正などをし、試運転、バグチェックなどをして、どうしてもわからないところがあったらまたコメント致します。
RagnAnet1373

2017/05/02 01:07

コメントが遅くなり申し訳ございません。 一応だんだんと遅くなった分のスクリプトを書き出します。
guest

0

現在、減速のみ行う用のボタンを作成し減速の関数を次のように変えたことで
押して離すとルーレットは多少かくつきますが0.1ずつ減速できました

swift

1 func speedDown(_ speed:Double,_ val:Double)->Float 2 { 3 var dSpeed = speed 4 let dVal = val 5 var ans:Double! 6 if(dSpeed > 0) 7 { 8 dSpeed = dSpeed - dVal 9 downSpeed = downSpeed - downval 10 ans = speed 11 } 12 else if(dSpeed <= 0) 13 { 14 ans = 1.0 15 downSpeed = 1.0 16 return Float(ans) 17 } 18 return Float(ans) 19 }

投稿2017/04/28 07:37

RagnAnet1373

総合スコア69

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問