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

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

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

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

Swift

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

Q&A

1回答

902閲覧

Swiftで時間をスライドバー(?)で指定するものを作成したい

Tommy2020

総合スコア18

Xcode

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

Swift

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

0グッド

0クリップ

投稿2020/08/23 03:04

編集2020/08/23 03:05

Swiftで時間をスライドバー(?)で指定するものを作成したいと考えています。
以下の画像の赤枠のようなものです。ネットでライブラリ等を探してみたのですが、なかなか実装方法が分かりません。
お分かりになる方、ご教授ください。
ちなみに画像は「Skyscanner」です。
イメージ説明

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

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

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

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

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

guest

回答1

0

ちょっと試してみました。こんな感じでしょうか。

イメージ説明

アイデアとしては、

  • スライダのつまみ(thumb)の座標を得る
  • その上に UILabel を表示させる

という流れになります。

具体的な流れについてはコードを見ていただければと思います。

ただし、

  • thumb の座標を得るのに今回は UIImageView を探す方法を用いた(teratailの過去問)。ただし、スライダの両端などに画像を追加した場合にはうまく動かないかもしれない。
  • 再利用について考えていない。
  • 目盛がない

などの問題もありますが、その辺りは質問者さんの方で改善していただければと思います。

Swift

1import UIKit 2 3class ViewController: UIViewController { 4 // スライダは Interface Builder で StoryBoard に配置 5 // コードベースで追加してもいい 6 @IBOutlet weak var slider: UISlider! 7 8 let sliderLabelView: UIView = { 9 let view = UIView() 10 view.backgroundColor = .white 11 12 view.layer.shadowColor = UIColor.lightGray.cgColor 13 view.layer.shadowOpacity = 1 14 view.layer.shadowRadius = 2 15 view.layer.shadowOffset = CGSize(width: 2, height: 2) 16 17 return view 18 }() 19 20 let sliderLabel: UILabel = UILabel() 21 22 // https://teratail.com/questions/271481 23 func getCenter(slider: UISlider) -> CGPoint? { 24 for subView in slider.subviews { 25 if subView is UIImageView { 26 let point = self.view.convert(subView.center, from: slider) 27 print(point) 28 print(self.view.center.x) 29 return point 30 } 31 } 32 return nil 33 } 34 35 override func viewDidLoad() { 36 super.viewDidLoad() 37 // Do any additional setup after loading the view. 38 39 // スライダーの初期値 40 slider.minimumValue = 0.0 41 slider.maximumValue = 24.0 42 } 43 44 // MARK: - スライダーに触れた瞬間の処理 45 // UISlider から Action を設定し、touch down と関連づける 46 @IBAction func sliderTouchDown(_ sender: UISlider) { 47 // 以前のアニメーションを削除する 48 sliderLabelView.layer.removeAllAnimations() 49 50 // Alpha を 1 に設定し、view の子ビューにする 51 sliderLabelView.alpha = 1.0 52 sliderLabelView.addSubview(sliderLabel) 53 view.addSubview(sliderLabelView) 54 } 55 56 // MARK: - スライダーを移動中の処理 57 // UISlider から Action を設定し、value changed と関連づける 58 @IBAction func sliderValueChanged(_ sender: UISlider) { 59 // 取得する値を離散値にするための処理 60 let value = Int(slider.value.rounded()) 61 62 // スライダーの thumb (丸い部分の中央座標を求める) 63 guard let thumbCenter = getCenter(slider: slider) else { 64 fatalError("Cannot get center of the slider thumb.") 65 } 66 67 // Skyscanner に似せるための処理。両端に達した時は ”指定しない” と表示する 68 if value == 0 || value == 24 { 69 sliderLabel.text = "指定しない" 70 } else { 71 sliderLabel.text = String(value) + "時以降" 72 } 73 74 // ラベルの幅を文字列と等しくする 75 sliderLabel.sizeToFit() 76 77 // UIView の幅と高さを計算 78 // ラベルより一回り大きくする 79 let width = sliderLabel.frame.width + 16 80 let height = sliderLabel.frame.height + 8 81 var viewX = thumbCenter.x - width / 2 82 83 guard let superView = sender.superview else { 84 fatalError("Cannot find superview of the slider.") 85 } 86 87 // ラベルが画面からはみ出るときには、はみ出ないように X 値を調整する 88 if viewX < 0 { 89 viewX = 0 90 } else if viewX > superView.frame.width - width { 91 viewX = superView.frame.width - width 92 } 93 94 // ラベルの Y 座標はボタンの上 32 ポイントの位置 95 let viewY = thumbCenter.y - height / 2 - 32 96 97 // UIViewの座標を設定し、文字の大きさに合わせて丸みをつけ、ラベルの中央を UIView の中央とする 98 sliderLabelView.frame = CGRect(x: viewX, y: viewY, width: width, height: height) 99 sliderLabelView.layer.cornerRadius = height / 2 100 sliderLabel.center = CGPoint(x: width / 2, y: height / 2) 101 } 102 103 // MARK: - スライダーから指を離したときの処理(スライダー内) 104 // UISlider から Action を設定し、touch up inside と関連づける 105 @IBAction func sliderTouchUpInside(_ sender: UISlider) { 106 dismissLabel() 107 } 108 109 // MARK: - スライダーから指を離したときの処理(スライダー外) 110 // UISlider から Action を設定し、touch up outside と関連づける 111 @IBAction func sliderTouchUpOutside(_ sender: UISlider) { 112 dismissLabel() 113 } 114 115 // MARK: - ラベルを消す処理 116 func dismissLabel() { 117 // スライダの thumb から指を離して 1.0 秒後に 0.5 秒かけてラベルをフェードアウトさせる 118 // 119 UIView.animate(withDuration: 0.5, delay: 1.0, 120 animations: { 121 self.sliderLabelView.alpha = 0.0 }, 122 completion: { flag in 123 if flag { 124 self.sliderLabelView.removeFromSuperview() 125 }} 126 ) 127 } 128}

投稿2020/08/24 13:15

TsukubaDepot

総合スコア5086

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問