Swiftで時間をスライドバー(?)で指定するものを作成したいと考えています。
以下の画像の赤枠のようなものです。ネットでライブラリ等を探してみたのですが、なかなか実装方法が分かりません。
お分かりになる方、ご教授ください。
ちなみに画像は「Skyscanner」です。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答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
総合スコア5086
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。