SwiftUIミニマリストチュートリアル40:SearchBarとTabViewの下部ナビゲーションの構築

序文

この章ではSearch、リスト検索とTabView下部ナビゲーションの検索を作成する方法を学習します。

前章では、シンプルなColourAtlaカラーカードアプリAppを完成させた後、関連コンテンツの改善を続けていきます。

SearchBar検索バー

1つ目はSearchBar検索バーです。検索バーの機能は、リストの内容を取得して、必要なカラーカードを見つけることです。

TextField入力ボックスを使用して検索バーを作成し、検索コンテンツを格納する変数SearchBarを宣言することから始めます。例:

@State var search = ""

次にSearchBar、検索バーのスタイルを設定します。例:

// MARK: 搜索

private var SearchBarView: some View {
    TextField("搜索颜色值", text: $search)
        .padding(7)
        .padding(.horizontal, 25)
        .background(Color(.systemGray6))
        .cornerRadius(8)
        .overlay(
            Image(systemName: "magnifyingglass")
                .foregroundColor(.gray)
                .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
                .padding(.leading, 8)
        )
        .padding(.horizontal, 10)
}

上記のコードでは、新しいビューを作成しSearchBarView、入力ボックスを検索バーとして使用し、コンテンツをTextFieldバインドしてから、修飾子を使用して検索バーのスタイルを絞り込みます。効果を確認するために、オリジナルを置き換えてみましょう。searchSearchBarCardTitleView

1.png

検索方法

色名の検索の相互作用を実装するには、リスト内の色見本を検索する方法を提供する必要があります。例:

// MARK: 搜索颜色方法

func searchColor() {
    let query = search.lowercased()
    DispatchQueue.global(qos: .background).async {
        let filter = cardItems.filter { $0.cardColorRBG.lowercased().contains(query) }
        DispatchQueue.main.async {
            withAnimation(.spring()) {
                self.cardItems = filter
            }
        }
    }
}

上記のコードでは、色を検索するメソッドを作成しました。searchColor検索テキストの内容に従ってカラーカード配列でカードの色値パラメータを検索することによりsearch一致が成功した場合、色検索して表示します。カラーカードアレイで。cardItemscardColorRBGcardItems

我们在SearchBarView视图中,当我们TextField输入框内容变化时调用这个方法。示例:

.onChange(of: search) { _ in
    if search != "" {
        searchColor()
    } else {
        search = ""
        getColors()
    }
}

2.png

上述代码中,我们在TextField输入框搜索内容search变量改变时,且search输入内容不为空时调用searchColor搜索颜色的方法,当search输入内容为空时,又重新调用getColors获取颜色的方法,这样,我们就实现了搜索颜色值的交互。

搜索栏切换

接下来,我们来实现标题栏搜索栏切换

我们尝试在标题栏右侧加入一个搜索图标,点击搜索图标切换到搜索栏,在搜索栏输入框右侧也增加一个取消按钮,点击取消又回到标题栏中。

先声明一个存储变量showSearchBar用于判断切换状态。

@State var showSearchBar = false

然后构建搜索按钮的样式和取消按钮的样式。示例:

// MARK: 搜索icon

private var SearchButtonView: some View {
    Button(action: {
        withAnimation(.easeOut) {
            showSearchBar.toggle()
        }
    }, label: {
        Image(systemName: "magnifyingglass")
            .font(.system(size: 20, weight: .bold))
            .foregroundColor(.gray)
    })
}

// MARK: 取消按钮

private var CloseButtonView: some View {
    Button(action: {
        withAnimation(.easeOut) {
            search = ""
            getColors()
            showSearchBar.toggle()
        }
    }, label: {
        Text("取消")
            .foregroundColor(.gray)
    })
}

3.png

上述代码中,我们创建了两个视图SearchButtonViewCloseButtonView。

SearchButtonView视图中,我们使用系统搜索图标做一个搜索按钮操作,点击时更改showSearchBar的状态。

CloseButtonView视图中,我们使用文字按钮做一个取消按钮的操作,点击时清空输入框的内容search,并且更改showSearchBar的状态,同时调用getColors获取颜色的方法。

完成这些后,我们进行样式的组装,示例:

// MARK: 搜索切换

private var SwitchSearchBar: some View {
    HStack(spacing: 20) {
        if showSearchBar {
            SearchBarView
            CloseButtonView
        } else {
            CardTitleView
            Spacer()
            SearchButtonView
        }
    }
    .padding(.top, 20)
    .padding(.bottom, 10)
    .padding(.horizontal)
    .zIndex(1)
}

上述代码中,我们构建了一个新的视图SwitchSearchBar

SwitchSearchBar视图中,我们根据showSearchBar的状态切换展示搜索栏还是标题栏的内容,并把SwitchSearchBar视图在ContentView主视图中呈现。

我们预览下效果:

4.png

TabView底部导航

我们创建一个新的SwiftUI文件,命名为TabberView

struct TabberView: View {

    @State private var selectedTab = 0

    var body: some View {
        TabView(selection: $selectedTab) {

            ContentView()
                .tabItem {
                    if self.selectedTab == 0 {
                        Image(systemName: "house")
                    } else {
                        Image(systemName: "house.fill")
                    }
                    Text("首页")
                }
                .tag(0)

            Text("我的")
                .tabItem {
                    if self.selectedTab == 1 {
                        Image(systemName: "person")
                    } else {
                        Image(systemName: "person.fill")
                    }
                    Text("我的")
                }
                .tag(1)
        }
        .accentColor(Color.Hex(0x409EFF))
    }
}

上述代码中,我们使用TabView来构建底部导航。

我们声明一个变量selectedTab来跟踪当前选中的是哪一个菜单,然后在TabView中绑定selectedTab的值。我们使用tabItem修饰符来显示当前菜单的内容,并且根据 selectedTab选中的状态修饰底部菜单的图标文字

最后我们给选中的菜单加上accentColor选中颜色。

我们预览下效果:

5.png

我们把之前章节完成的MineView我的视图也换到TabView底部菜单中,预览看下效果:

6.png

LoadingView加载动画

加载样式

以前はProgressView、ロード時のデフォルトのアニメーションとして、ColourAtlaカラーカードとしてApp使用しProgressView、ロードアニメーションとして使用していましたが、これは十分にエレガントではありませんでした。

最初に。という名前の新しいファイルを作成することによりSwiftUI、公式のrotationEffect修飾子を使用して読み込みアニメーションを作成できますSwiftUILoadingView

まず、回転状態を格納する変数を宣言してから、回転した画像を作成しiconます。

import SwiftUI

struct LoadingView: View {

    @State var show: Bool = false

    var body: some View {
        Image(systemName: "sun.min.fill")
            .resizable()
            .foregroundColor(Color.Hex(0xFAD0C4))
            .aspectRatio(contentMode: .fit)
            .frame(width: 60, height: 60)
            .rotationEffect(.degrees(show ? 360 : 0))
    }
}

8.png

上記のコードでは、モディファイアをImage使用してロードされたアイコンを作成し、状態に応じて回転させます。rotationEffectshow

ロード方法

読み込みアイコンを回転させるために、 1秒ごとに状態doAnimationを切り替えるメソッドを作成しますshow

func doAnimation() {
        withAnimation(Animation.easeInOut(duration: 1).repeatForever(autoreverses: true)) {
            show.toggle()
        }
    }

Image完了すると、を提示するときに呼び出すメソッドdoAnimation

9.png

最後に、オリジナルをContentViewに置き換えて、効果を確認します。LoadingViewProgressView

10.png

プロジェクトプレビュー

7.png

是非、お試しください!

このコラムがお役に立てば、いいね、コメント、フォローしてください〜

ナゲッツテクノロジーコミュニティのクリエイター署名プログラムの募集に参加しています。リンクをクリックして登録し、送信してください。

おすすめ

転載: juejin.im/post/7117838599000686623
おすすめ