0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SwiftUIで作る(疑似)ループピッカー

Last updated at Posted at 2025-02-17

タイマーアプリを作るときに0から9までの数字を選択できる、かつ、0の前が9で9の次が0とループするPickerを作りました。
割とシンプルできれいに書けたので実際のアプリに使っているコードそのままですがサンプルとして残しておきます。

import SwiftUI

struct DigitPicker: View {
    private let label: String
    private let range: [Int]
    @Binding private var selection: Int
    @State private var innerSelection: Int = 0
    private let loop = 100
    
    init(_ label: String, _ range: [Int], _ selection: Binding<Int>) {
        self.label = label
        self.range = range
        self._selection = selection
    }
    
    var body: some View {
        Picker(label, selection: $innerSelection) {
            ForEach(0..<(range.count * loop), id: \.self) { i in
                let value = range[i % range.count]
                Text("\(value)").tag(i)
            }
        }
        .pickerStyle(.wheel)
        .labelsHidden()
        .frame(minWidth: 30, maxWidth: 30, minHeight: 50, maxHeight: 50)
        .clipped()
        .onAppear() {
            innerSelection = selection + (range.count * loop / 2)
        }
        .onChange(of: innerSelection) {_, _ in
            selection = innerSelection % range.count
        }
    }  
}

簡単に解説しておくと

  • loop回繰り返して0から9までの選択肢を用意
  • 初期描画時に同じ値を表す真ん中の選択肢に選択を変更
  • onChangeで選択肢から実際の数字(0から9)に変換
    上記をすることで疑似的にループを実現しています。
    疑似なのでひたすらピッカーを回し続ければ端でループは途切れますが、実用上は問題ないと割り切った作りになってます。

実際の動作は

ComposeTimerで確認できます。
無料アプリなので良かったらダウンロードして挙動を確かめてみてください。
https://apps.apple.com/jp/app/composetimer/id6740627031

アプリ起動後に右上のプラスから新規タイムラインを作成、タイムライン編集画面でパートのプラスから開くパート編集画面の項目「時間」でDigitPickerを6つ並べてパートの所要時間を入力できるようにしています。

所要時間.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?