ご存知のように、AppleのiOS SDKには、無数の組み込みUIコンポーネントが含まれています。ボタン、コンテナ、ナビゲーション、タブ付きレイアウトなど、名前を付けることができます。必要なものはほとんどすべて揃っています。またはそれは?
これらの基本的なコンポーネントはすべて、基本的な構造化されたUIを作成できますが、ボックスの外に出る必要がある場合はどうなりますか。いつ iOS開発者 デフォルトでSDKでサポートされていないある種の動作を構築する必要がありますか?
これらのケースの1つは UITabBar 、タブ間をスワイプする機能がなく、タブを切り替えるためのアニメーションもありません。
かなりの量の検索を行った後、Githubで有用なライブラリを1つだけ見つけることができました。残念ながら、ライブラリはアプリケーションの実行中に多くの問題を引き起こしましたが、一見エレガントなソリューションのように見えました。
ラズベリーパイ3Linuxサーバー
言い換えれば、私はライブラリが非常に使いやすいと感じましたが、バグがあり、明らかにその使いやすさを上回り、 問題を引き起こす傾向がありました 。あなたがまだ興味を持っている場合は、ライブラリはこの下にあります リンク 。
それで、いくつかの考えと多くの検索の後、私は自分自身のソリューションを実装し始め、私は自分自身に言いました: 「ねえ、スワイプにページビューコントローラーとネイティブUITabBarを使用するとどうなるでしょうか。これら2つをグループ化して、タブバーをスワイプまたはタップしながらページインデックスを処理するとどうなりますか?」
最終的に、私は解決策を思いつきましたが、後で説明するように、それはややトリッキーであることがわかりました。
構築するタブバーアイテムが3つあると想像してください。つまり、タブアイテムごとに3つのページ/コントローラーが自動的に表示されます。
この場合、これら3つのビューコントローラーをインスタンス化する必要があります。また、タブバーアイテムを作成したり、タブが押されたとき、またはユーザーが変更したいときに状態を変更したりするには、タブバー用に2つのプレースホルダー/空のビューコントローラーが必要です。プログラムでタブインデックス。
このために、Xcodeを掘り下げて、いくつかのクラスを作成して、これらがどのように機能するかを確認しましょう。
これらのスクリーンショットでは、最初のタブバーアイテムが青色で、次にユーザーが右側のタブ(黄色)にスワイプし、最後の画面に3番目のアイテムが選択されていることが示されているため、ページ全体が黄色で表示されます。
それでは、この機能について詳しく見ていき、iOS用のスワイプ可能なタブバーの簡単な例を書いてみましょう。まず、新しいプロジェクトを作成する必要があります。
私たちのプロジェクトに必要な前提条件は非常に基本的です:MacにインストールされたXcodeおよびXcodeビルドツール。
新しいプロジェクトを作成するには、MacでXcodeアプリケーションを開き、[ 「新しいXcodeプロジェクトを作成する」 次に、プロジェクトに名前を付け、最後に作成するアプリケーションのタイプを選択します。選択するだけです 「シングルビューアプリ」 [次へ]を押します。
ご覧のとおり、次の画面では、いくつかの基本情報を入力する必要があります。
注意: 開発者アカウントをお持ちでない場合は、シミュレーターでも実行できます。
[次へ]ボタンを押すと、スワイプ可能なタブバーの作成を開始する準備が整います。
node.js:サーバー側のJavaScript
すでにご存知のように、新しいアプリを作成すると、メインのViewController
が既に存在します。クラスとMain.Storyboard
。
設計を開始する前に、ジョブのUI部分に進む前に、必要なすべてのクラスとファイルを作成して、すべてがセットアップされ、実行されていることを確認しましょう。
プロジェクト内のどこかで、いくつかの新しいファイルを作成するだけです-> TabbarController.swift 、 NavigationController.swift 、 PageViewController.swift 。
私の場合はこんな感じです。
の中に AppDelegate 他のすべてのメソッドを削除できるため、ファイルにはdidFinishLaunchingWithOptions
のみを残します。
didFinishLaunchingWithOptions
内で、以下の行をコピーして貼り付けるだけです。
window = UIWindow(frame: UIScreen.main.bounds) window?.rootViewController = NavigationController(rootViewController: TabbarController()) window?.makeKeyAndVisible() return true
と呼ばれるファイルからすべてを削除します ViewController.swift 。後でこのファイルに戻ります。
まず、のコードを書いてみましょう NavigationController.swift 。
import Foundation import UIKit class NavigationController: UINavigationController { override func viewDidLoad() { super.viewDidLoad() navigationBar.isTranslucent = true navigationBar.tintColor = .gray } }
これで、単純なUINavigationController
を作成しました。ここでは、灰色のTintColorを備えた半透明のバーがあります。これですべてです。
これで、PageViewController
に進むことができます。
その中で、前に説明したファイルよりも少し多くコーディングする必要があります。
このファイルには、1つのクラス、1つのプロトコル、いくつかのUIPageViewController
が含まれています。データソース、およびデリゲートメソッド。
結果のファイルは次のようになる必要があります。
Wordでxmlファイルを開く
ご覧のとおり、PageViewControllerDelegate
という独自のプロトコルを宣言しました。これは、スワイプが処理された後にページインデックスが変更されたことをタブバーコントローラーに通知する必要があります。
import Foundation import UIKit protocol PageViewControllerDelegate: class { func pageDidSwipe(to index: Int) }
次に、PageViewController
という新しいクラスを作成する必要があります。このクラスは、View Controllerを保持し、特定のインデックスでページを選択し、スワイプも処理します。
最初の実行で最初に選択されたコントローラーがセンタービューコントローラーであると想像してみましょう。この場合、1に等しいデフォルトのインデックス値を割り当てます。
class PageViewController: UIPageViewController { weak var swipeDelegate: PageViewControllerDelegate? var pages = [UIViewController]() var prevIndex: Int = 1 override func viewDidLoad() { super.viewDidLoad() self.dataSource = self self.delegate = self } func selectPage(at index: Int) { self.setViewControllers( [self.pages[index]], direction: self.direction(for: index), animated: true, completion: nil ) self.prevIndex = index } private func direction(for index: Int) -> UIPageViewController.NavigationDirection { return index > self.prevIndex ? .forward : .reverse } }
ここでわかるように、変数pages
があり、これにはすべてのViewControllerの参照が含まれます。
変数prevIndex
最後に選択したインデックスを保存するために使用されます。
単にselectPage
と呼ぶことができます選択したインデックスを設定するためのメソッド。
ページインデックスの変更をリッスンする場合は、swipeDelegate
にサブスクライブする必要があり、ページをスワイプするたびに、ページインデックスが変更されたことが通知され、さらに現在のインデックスも受信します。
メソッドの方向は、UIPageViewController
のスワイプ方向を返します。このクラスのパズルの最後のピースは、デリゲート/データソースの実装です。
パートナーシップと法人税の利点
幸い、これらの実装は非常に簡単です。
extension PageViewController: UIPageViewControllerDataSource { func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { guard let viewControllerIndex = pages.firstIndex(of: viewController) else { return nil } let previousIndex = viewControllerIndex - 1 guard previousIndex >= 0 else { return nil } guard pages.count > previousIndex else { return nil } return pages[previousIndex] } func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { guard let viewControllerIndex = pages.firstIndex(of: viewController) else { return nil } let nextIndex = viewControllerIndex + 1 guard nextIndex nextIndex else { return nil } return pages[nextIndex] } } extension PageViewController: UIPageViewControllerDelegate { func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) { if completed { guard let currentPageIndex = self.viewControllers?.first?.view.tag else { return } self.prevIndex = currentPageIndex self.swipeDelegate?.pageDidSwipe(to: currentPageIndex) } } }
上記のように、3つの方法があります。
prevIndex
次に、デリゲートメソッドを呼び出して、スワイプが正常に終了したことを親ViewControllerに通知します。これでようやくUITabBarController
を書くことができます実装:
import UIKit class TabbarController: UITabBarController { let selectedColor = UIColor.blue let deselectedColor = UIColor.gray let tabBarImages = [ UIImage(named: 'ic_music')!, UIImage(named: 'ic_play')!, UIImage(named: 'ic_star')! ] override func viewDidLoad() { view.backgroundColor = .gray self.delegate = self tabBar.isTranslucent = true tabBar.tintColor = deselectedColor tabBar.unselectedItemTintColor = deselectedColor tabBar.barTintColor = UIColor.white.withAlphaComponent(0.92) tabBar.itemSpacing = 10.0 tabBar.itemWidth = 76.0 tabBar.itemPositioning = .centered setUp() self.selectPage(at: 1) } }
ご覧のとおり、デフォルトのプロパティとスタイルでTabbarController
を作成します。選択されたバーアイテムと選択解除されたバーアイテムの2つの色を定義する必要があります。また、タブバーアイテムの画像を3つ紹介しました。
viewDidLoad
では、タブバーのデフォルト構成を設定し、ページ#1を選択しているだけです。これが意味するのは、スタートアップページがページ番号1になるということです。
private func setUp() { guard let centerPageViewController = createCenterPageViewController() else { return } var controllers: [UIViewController] = [] controllers.append(createPlaceholderViewController(forIndex: 0)) controllers.append(centerPageViewController) controllers.append(createPlaceholderViewController(forIndex: 2)) setViewControllers(controllers, animated: false) selectedViewController = centerPageViewController } private func selectPage(at index: Int) { guard let viewController = self.viewControllers?[index] else { return } self.handleTabbarItemChange(viewController: viewController) guard let PageViewController = (self.viewControllers?[1] as? PageViewController) else { return } PageViewController.selectPage(at: index) }
setUpメソッド内で、2つのプレースホルダービューコントローラーを作成したことがわかります。これらのプレースホルダーコントローラーはUITabBar
に必要ですの数のため タブバーアイテム 使用しているViewControllerの数と同じである必要があります。
思い出せる場合は、UIPageViewController
を使用しますコントローラを表示するためですが、UITabBar
の場合、完全に機能させるには、すべてのView Controllerをインスタンス化して、バーアイテムをタップしたときに機能するようにする必要があります。したがって、この例では、 placeholderviewcontroller#0 そして #2 空のViewControllerです。
中央のビューコントローラーとして、PageViewController
を作成します3つのビューコントローラーを備えています。
private func createPlaceholderViewController(forIndex index: Int) -> UIViewController { let emptyViewController = UIViewController() emptyViewController.tabBarItem = tabbarItem(at: index) emptyViewController.view.tag = index return emptyViewController } private func createCenterPageViewController() -> UIPageViewController? { let leftController = ViewController() let centerController = ViewController2() let rightController = ViewController3() leftController.view.tag = 0 centerController.view.tag = 1 rightController.view.tag = 2 leftController.view.backgroundColor = .red centerController.view.backgroundColor = .blue rightController.view.backgroundColor = .yellow let storyBoard = UIStoryboard.init(name: 'Main', bundle: nil) guard let pageViewController = storyBoard.instantiateViewController(withIdentifier: 'PageViewController') as? PageViewController else { return nil } pageViewController.pages = [leftController, centerController, rightController] pageViewController.tabBarItem = tabbarItem(at: 1) pageViewController.view.tag = 1 pageViewController.swipeDelegate = self return pageViewController } private func tabbarItem(at index: Int) -> UITabBarItem { return UITabBarItem(title: nil, image: self.tabBarImages[index], selectedImage: nil) }
上記の1番目と2番目のメソッドは、私たちのinitメソッドです。 ページビュー コントローラ。
メソッドtabbar
アイテムはtabbar
を返すだけですインデックスのアイテム。
ご覧のとおり、createCenterPageViewController()
内ビューコントローラごとにタグを使用しています。これは、どのコントローラーが画面に表示されているかを理解するのに役立ちます。
次に、おそらく最も重要な方法であるhandleTabbarItemChange
について説明します。
private func handleTabbarItemChange(viewController: UIViewController) { guard let viewControllers = self.viewControllers else { return } let selectedIndex = viewController.view.tag self.tabBar.tintColor = selectedColor self.tabBar.unselectedItemTintColor = selectedColor for i in 0..この方法では、ViewControllerをパラメーターとして使用しています。このViewControllerから、選択したインデックスとしてタグを取得します。タブバーには、選択した色と選択していない色を設定する必要があります。
次に、すべてのコントローラーをループして、i == selectedIndex
かどうかを確認する必要があります。
次に、画像をとしてレンダリングする必要があります オリジナルのレンダリングモード それ以外の場合は、画像をとしてレンダリングする必要があります テンプレートモード 。
企業がサプライヤーの力を減らすことができる最も一般的な方法の1つは何ですか
を使用して画像をレンダリングする場合 テンプレートモード 、アイテムの色合いの色から色を継承します。
ほぼ完了です。 UITabBarControllerDelegate
から2つの重要な方法を紹介する必要がありますおよびPageViewControllerDelegate
。
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool { self.selectPage(at: viewController.view.tag) return false } func pageDidSwipe(to index: Int) { guard let viewController = self.viewControllers?[index] else { return } self.handleTabbarItemChange(viewController: viewController) }
1つ目は、タブアイテムを押すと呼び出され、2つ目は、タブ間をスワイプすると呼び出されます。
まとめ
すべてのコードをまとめると、ジェスチャーハンドラーの独自の実装を作成する必要がなく、タブバーアイテム間でスムーズなスクロール/スワイプを実現するために多くのコードを作成する必要がないことに気付くでしょう。
ここで説明する実装は、すべてのシナリオに理想的なものではありませんが、少しのコードでこれらの機能を作成できる、風変わりで迅速かつ比較的簡単なソリューションです。
最後に、私のアプローチを試してみたい場合は、 GitHubリポジトリ 。ハッピーコーディング!
基本を理解する
iPhoneの主なユーザーインターフェイス要素は何ですか?
iOSで最も頻繁に使用されるUIコンポーネントは、UIView、UIButton、UIImageView、UITextfield、UILabel、およびUITextviewです。
UIKitとは何ですか?
UIKitフレームワークは、iOSまたはtvOSアプリのインフラストラクチャを提供します。インターフェースを実装するためのウィンドウとビューのアーキテクチャ、マルチタッチやその他のタイプの入力を配信するためのイベント処理、ユーザー、システム、アプリ間の相互作用を管理するために必要なメイン実行ループを提供します。
マテリアルデザインiOSとは何ですか?
マテリアルデザインは、Googleによって作成されたスタイルです。マテリアルデザインの基本的なメタファーは、3D空間の平らな紙です。これは、iOSではなくAndroidアプリケーションを設計するためのデフォルトのアプローチです。ただし、GoogleはiOSアプリやWebアプリなど、他のプラットフォームでも使用しています。