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

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

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

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

Q&A

解決済

1回答

3141閲覧

Swift3 UISliderが動かない・・・

mitci

総合スコア37

Swift

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

0グッド

0クリップ

投稿2017/10/13 12:52

編集2017/10/20 12:45

###実現したいこと
UISliderのツマミをわずかに動かした時にも、ちゃんとメソッドを呼び出してほしい。

###発生している問題
MPMusicPlayerController()の再生時間を取得するためのいわゆるシークバーをUISliderを使って設置したのですが、 ツマミをわずかに動かした時 の反応がありません・・・。
ツマミを大きく動かせばちゃんと接続したIBActionのメソッドが呼び出されるのですが、480pxの長さのスライダーのツマミを20px程度動かしただけではメソッドが呼ばれません・・・。
スライダーに接続しているIBActionは以下の通りです。

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

swift

1 2seekBarSlider.minimumValue = 0 3seekBerSlider.maximumValue = Float(player.nowPlayingItem.playbackDuration) 4 5@IBAction func seekBarSlidertouchDown(_ sender: UISlider) { 6 sliderTimer.invalidate() 7 //ツマミの位置更新タイマーを停止させる 8 } 9//ツマミを触った瞬間 10@IBAction func seekBarSliderValueChanged(_ sender: UISlider) { 11 let min = Int(sender.value) / 60 12 let sec = Int(sender.value) % 60 13 timeLabel.text = String(format: "%02d:%02d", min, sec) 14 //"00:00"のタイムラベルを更新する 15} 16//ツマミを移動させた時 17@IBAction func seekBarSliderTouchUpInside(_ sender: UISlider) { 18 player.currentPlaybackTime = TimeInterval(sender.value) 19 sliderTimerStart() 20 //ツマミの位置更新のタイマーを再開させる 21 } 22//ツマミから指を離した時(inside) 23 @IBAction func seekBarSliderTouchUpOutside(_ sender: UISlider) { 24 player.currentPlaybackTime = TimeInterval(sender.value) 25 sliderTimerStart() 26 //ツマミの位置更新のタイマーを再開させる 27 } 28//ツマミから指を離した時(outside)

valueChangedメソッドにsenderValueを代入してしまうと、ツマミを少しでも動かすたびに曲がその値の時間で再生されまくってしまうため、
touchUpInsidetouchUpOutsideツマミの位置が確定した瞬間 に再生時間が変わるようにしています。
標準のミュージック.appのシークバーの挙動と同じようにしたくて、このように処理をしているのですが、
なぜか ツマミをわずかに動かしたとき だけtouchUpInsidetouchUpOutsideのメソッドが呼ばれません。

###試したこと
UISliderの仕様でしかたのないことなのでしょうか?
どのIBActionを使ったらいいか、などについては、
かなり我流で設定したところもあるので、問題点がよくわかりません・・・

ただ、valueChangedだけだと曲を再生中にツマミに触れると曲が飛び飛びに再生されまくってしまうので、ツマミを掴んでも曲はそのまま再生され続け、ツマミから指を離した瞬間にちゃんとその瞬間の値を再生時間に代入できれば、どんな処理を施してもかまいません。
よろしくお願いします。

###理想の動き
スライダーのツマミに触れても曲は流れたまま、1秒前や2秒後などのごく僅かにツマミを移動させ、
指を離した瞬間にその秒数から曲がスタート

ごく普通のシークバーです。
現在だと曲にもよりますが前後15秒くらいのツマミの移動は無視されます…

「01:24」などの時間表示は動いているのでvalueChangedは僅かな移動でも反応しています…

###追記
すいません・・・
UISliderを配置しているViewの親ビューにはtapGestureを登録してあり、UIGestureRecognizerDelegateshouldReceiveメソッドでどのビューにtouchしたかを以下のように判断させています。

swift

1public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { 2 if touch.view == self.subView { 3 return false 4 } 5 return true 6 }

これを外すと、UISliderに触った瞬間に親ビューにaddしたtapGesture#selectorメソッドが発動してしまいます・・・

###補足情報(言語/FW/ツール等のバージョンなど)
swift3 xcode8.3.2

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

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

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

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

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

guest

回答1

0

ベストアンサー

なぜか ツマミをわずかに動かしたとき だけtouchUpInsideやtouchUpOutsideのメソッドが呼ばれません

そんなことはないと思います。
一度、各Action関数の中身をprint(sender.value)だけにして確認してみて下さい。

他の処理(タイマー処理っぽいのは何でしょうか?)が悪さをしているのではないでしょうか?

テストコード

swift

1//valueChanged 2@IBAction func valueChanged(_ sender: UISlider) { 3 print("[valueChanged]", sender.value) 4} 5 6//touchUpInside/touchUpOutside共用 7@IBAction func touchUp(_ sender: UISlider) { 8 print("[touchUp]", sender.value) 9}

投稿2017/10/16 04:36

編集2017/10/17 01:41
fuzzball

総合スコア16731

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

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

mitci

2017/10/16 12:54 編集

print関数を使ってテストをしてみましたが、やはり20~30px程度のツマミ移動ではvalueChangedメソッドのみしか反応せず、touchUpInsideなどは呼び出されませんでした。 タイマーの処理は0.1秒ごとにツマミの位置を更新するためのものです。 touchDownメソッドで「ツマミ位置更新タイマー」を止めて -> valueChangedで時間表示だけを変化させて -> touchUpメソッドでその時点の秒数から再生を再開するという処理です。 50〜60px以上の移動では適宜処理が行われるのですが、小さな移動では「指を離した」ということが認識されていないようなのです・・・ そのほかのアプリ等ではタッチ操作やスワイプ操作はうまくいくために実機ハードの問題でもなさそうですし、 大きくツマミを移動させた場合はちゃんと処理をするというあたり、本当にコードの問題なのかというところもあり・・・わからなくなってしまいました。
fuzzball

2017/10/17 01:39

「print関数を使ってテスト」というのは、他の処理をコメントアウトなどしてテストしましたか? 一度、別プロジェクトを作ってテスト出来ますか? 私が試したコードを回答に追記しておきます。
mitci

2017/10/20 12:45 編集

新規プロジェクトでコードを試しました。 おっしゃる通り、ちゃんとスライダーが働いたので、よくよく問題のあるコードを検証したところ、 ほんとうに大変申し訳ない話なのですが、UISliderを置いたViewにタップジェスチャーをaddしており、それが悪さをしていました・・・ そのUISliderを置いたViewの親ビューに別のタップジェスチャーをaddしており、そちらが「UISliderを置いたView」内で反応しないように、なんの処理もしないタップジェスチャーを「UISliderを置いたView」にaddしていたんです・・・ そのため、現在gestureRecognizerDelegateを使用して同じように子ビューをタップした時に反応をしないように書き換えたのですが、やはり「わずかなスワイプ」のみ反応がありません・・・ すいません。情報を追記しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問