0
0

swift uiで検索プルダウンを作成

Last updated at Posted at 2024-01-19

イメージはこんな感じ
スクリーンショット 2024-01-19 15.56.44.png

import SwiftUI

// 新しいデータ型
struct YourNewDataType: Identifiable {
    var id: UUID
    var name: String
    // 他のプロパティや初期化処理を必要に応じて追加
}

// サンプルデータ
let yourNewDataArray: [YourNewDataType] = [
    YourNewDataType(id: UUID(), name: "Item 1"),
    YourNewDataType(id: UUID(), name: "Item 2"),
    // 他のデータを追加
]

struct ContentView: View {
    @State private var searchText = ""
    @State private var isPopupPresented = false
    @State private var selectedData: YourNewDataType?

    var body: some View {
        ZStack {
            TextField("", text: $searchText)
                .frame(width: 370, height: 42, alignment: .leading)
                .padding(.leading, 10)
                .border(Color.gray, width: 1)
                .padding(.bottom, 30)
                .onTapGesture {
                    UIApplication.shared.sendAction(#selector(UIResponder.becomeFirstResponder), to: nil, from: nil, for: nil)
                    isPopupPresented = true
                }
                .overlay(
                    isPopupPresented ?
                    VStack() {
                        if searchText.isEmpty {
                            VStack(spacing: 0) {
                                siteScrollView(data: yourNewDataArray)
                            }
                        } else {
                            VStack(spacing: 0) {
                                filteredSiteScrollView(data: yourNewDataArray)
                            }
                        }
                    }
                    .frame(width: 380, alignment: .leading)
                    .border(Color.gray, width: 1)
                    : nil
                )
        }
    }

    // siteScrollView 関数の修正
    func siteScrollView(data: [YourNewDataType]) -> some View {
        return ScrollView {
            VStack(spacing: 0) {
                ForEach(data) { item in
                    VStack(spacing: 0) {
                        Text(item.name)
                            .onTapGesture {
                                self.selectedData = item
                                isPopupPresented = false
                                searchText = item.name
                            }
                            .frame(width: 370, alignment: .leading)
                            .padding(10)

                        Rectangle()
                            .frame(height: 1)
                            .foregroundColor(Color.gray)
                            .frame(width: 370, alignment: .leading)
                    }
                }
            }
        }
        .background(Color.gray) // 仮の色設定
        .frame(height: 160)
    }

    // filteredSiteScrollView 関数の修正
    func filteredSiteScrollView(data: [YourNewDataType]) -> some View {
        let filteredData = data.filter { $0.name.localizedCaseInsensitiveContains(searchText) }

        return ScrollView {
            VStack(spacing: 0) {
                ForEach(filteredData) { item in
                    VStack(spacing: 0) {
                        Text(item.name)
                            .onTapGesture {
                                self.selectedData = item
                                isPopupPresented = false
                                UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
                                searchText = item.name
                            }
                            .frame(width: 370, alignment: .leading)
                            .padding(10)

                        if filteredData.count > 1 {
                            Rectangle()
                                .frame(height: 1)
                                .foregroundColor(Color.gray)
                                .frame(width: 370, alignment: .leading)
                        }
                    }
                }
            }
        }
        .frame(height: filteredData.count > 1 ? 80 : 40)
        .background(Color.gray) // 仮の色設定
    }
}

iPadではsheetやpopoverとTextField+MENUの組み合わせでなんとか検索プルダウン的なのはできたんですが、iPhoneで横画面の場合全画面表示になってしまいそちらでは対応できず、パッケージなどもなかったので仕方なく独自で作成しました

できたこと

横並びにしたい場合HStackでテキストとテキストフィールド部分囲えばできます
テキストフィールドをクリアしたいなどの場合はオーバーレイをもう一つ追加してそこでボタンやイメージなどを追加すれば可能です(offsetなどで場所を操作する必要はある)

まとめ

Webでよく使われる検索プルダウンがiosでは存在しなくてどうしようかなってずっと悩みながらトライしてたんですが、結局色々探したけどできなかったし、記事も見つからなかったので自作するしかないかって諦めて久々に頭を使いました

多分Webと同じにしたいとかそんな理由でiosでも検索プルダウンを実装してくれみたいなことを言われる方はこれからもいるだろうな

また自分も言われるだろうし、記事もなかったので自身の忘備録を兼ねて投稿です

どなたかの参考になれば幸いです。ではまた

0
0
5

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