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

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

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

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

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

スライダー

GUIのグラフィカルウィジェットのひとつです。インジケーターを動かすことで値を調節可能とします。

Swift

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

Q&A

解決済

2回答

447閲覧

デリゲードメソッドの処理が終わった後に任意のメソッドを実行したい

techiro

総合スコア10

iOS

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

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

スライダー

GUIのグラフィカルウィジェットのひとつです。インジケーターを動かすことで値を調節可能とします。

Swift

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

0グッド

0クリップ

投稿2020/06/25 13:04

編集2020/06/25 13:11

前提・実現したいこと

テーブルを使用してセルをタップした際の処理に、
スライダーの値を更新するコードと、スライダーの値に応じてViewを描画するコードを書いています。
しかし、実際にセルをタップしてみると、タップする前のスライダーの値からViewを描画してしまいます。

現在の流れとしては、
①→cell1をタップ
②→(スライダーの値はcellの中に含まれている値が反映されている)
③→タップ時のスライダー位置(sPositionSliderとePositionSlider)からカスタムviewが描画
④→スライダーの位置が変更(cellに含まれている値)

③、④の処理の順番がどうしても入れ替えられません。

質問としては、「デリゲートメソッドの処理を終わらせた後に任意のメソッドを実行したい」としています。しかし、質問の方法でやりたいことが実現できるかどうかの判断がついていないので、
できれば実現したいことを踏まえて何かわかる方がいらしたら回答よろしくお願いします。

該当のソースコード

swift

1 2struct Info{ 3 let sPosition: Float 4 let ePosition: Float 5} 6 7 @IBOutlet weak var sPositionSlider: UISlider! 8 @IBOutlet weak var ePositionSlider: UISlider! 9   var sPoint: CGPoint = CGPoint.zero 10 var ePoint: CGPoint = CGPoint.zero 11 var infos = [Info]() 12//infosの中にスライダーのデータが入っている。ex)infos[0].sPosition = 0.61, infos[0].ePosition = 0.83 13 14 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 15 print("tapped") 16//スライダーの値を更新 17 sPositionSlider.value = infos[indexPath.row].sPosition 18 ePositionSlider.value = infos[indexPath.row].ePosition 19//   print(sPositionSlider.value)→変更後になっている。 20 updateDrawPosition() 21//sPointからePointまでの範囲に色をつけて返す処理 22 fillColorView.fillColor(sP: sPoint, eP: ePoint) 23 } 24 25 26 27//更新されたスライダーの値を取得してCGPoint型の値を代入 28 func updateDrawPosition() { 29//print(sPositionSlider.value)→変更後になっている。 30//値は変更されているが位置が変更されていないから思った通りにならない? 31 sPoint= getPosition(sPositionSlider) 32 ePoint = getPosition(ePositionSlider) 33 } 34 35//スライダーの値をCGPoint型で返す 36 func getPosition(_ slider:UISlider)->CGPoint{ 37 for i in slider.subviews { 38 if i is UIImageView { 39 let point = self.view.convert(i.center, from: slider) 40 return point 41 } 42 } 43 return CGPoint.zero 44 } 45

補足情報(FW/ツールのバージョンなど)

Swift 5

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

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

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

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

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

guest

回答2

0

ベストアンサー

getPosition で UISlider の subviews にアクセスしていますが、iOS のバージョンが変わると UI 部品の作りが変わって動かなくなる可能性があり、あまり良くないです。UISlider には各部の座標を求めるメソッド (本来はカスタマイズ用ですが…) があるので、それを使いましょう。タイミングの問題もなくなるはず。
参考: UISlider - Apple Developer Documentation

swift

1 func getPosition(_ slider: UISlider) -> CGPoint { 2 let track = slider.trackRect(forBounds: slider.bounds) 3 let thumb = slider.thumbRect(forBounds: slider.bounds, trackRect: track, value: slider.value) 4 return self.view.convert(CGPoint(x: thumb.midX, y: thumb.midY), from: slider) 5 }

投稿2020/06/25 14:18

編集2020/06/25 14:27
hoshi-takanori

総合スコア7893

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

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

techiro

2020/06/25 14:54

回答ありがとうございます。 思った通りの処理を実現することができました!
guest

0

コメントの通り、再描画が行われていない為に希望の動作になっていないかと思われます。
一応、setNeedsDisplayという再描画を促す関数はありますが、即時性がないですよね。
パッと思いついた方法だと下記の2つの方法があります。

  1. valueの値を利用してpointを求める
let point = self.view.convert(i.center, from: slider) return point

この部分をminimumValue/maximumValue/valueの値で求めるようにするとどうでしょうか。

  1. タイミングをずらす
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) { //スライダーの値を更新 sPositionSlider.value = infos[indexPath.row].sPosition ePositionSlider.value = infos[indexPath.row].ePosition } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { updateDrawPosition() //sPointからePointまでの範囲に色をつけて返す処理 fillColorView.fillColor(sP: sPoint, eP: ePoint) }

というように、willselectでスライダーの値を更新し、didselectで描画位置を取得
※必要であればwillselectのタイミングで各スライダーのsetNeedsDisplayを呼び出す

実際試してないので確証はありません。。

投稿2020/06/25 13:38

編集2020/06/25 13:39
Kapustin

総合スコア1186

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

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

techiro

2020/06/25 14:09

回答ありがとうございます。 sliderのvalueは変更できているので、1番目の方法で実現できる可能性が高いですね! 早速やってみます。 質問に戻るのですが、デリゲートメソッドが終了したあとに、別のメソッドを実行することは可能なのでしょうか?
Kapustin

2020/06/25 14:24

デリゲートメソッド内で呼び出すわけではなく、呼び出し後に何かしたい場合は、移譲元(UITableView)での処理が必要です。 移譲元も自分がアクセスできるのであれば、直接書き加えるか、(privateでなければ)継承して処理を追加するなどが可能です。 今回の場合はUITableViewを継承したカスタムクラスを作成すれば、ある程度は自由に処理できるかと思います。(private関数もあるかと思うので、あくまで「ある程度」と表現しておきます。)
techiro

2020/06/25 14:51

回答ありがとうございます。 移譲元での処理が必要なのですね。 自分でクラスをいじった経験がないので、まだ理解できていませんが、簡単なプログラムを書いて学んでいきたいと思います! 回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問