13
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Swift】Firebase UIをカスタマイズしてお洒落なサインイン画面を作る

Last updated at Posted at 2021-03-03

環境

  • Xcode Version 12.3 (12C33)
  • FirebaseUI (10.0.2)
  • iOS 13 以上

目標

  • Firebase UI を用いて楽にサインイン処理を実装したい
  • デフォルトのデザインがあまりにも寂しすぎるためきれいにしたい
デフォルトのFirebase UI によるサインイン画面
Simulator Screen Shot - iPhone SE (iOS 14.2.2nd generation) - 2021-03-03 at 18.16.42.png

直したいポイント

  1. フルスクリーン表示にしたい
  2. "Cancel" を非表示にしたい
  3. "Welcome" は "サインイン" にしたい
  4. そもそも NavigationBar 自体非表示にしたい
  5. サービス選択ボタンに丸みをつけたい
  6. 背景色を変更し画像を追加したい

Firebase UI でデフォルトのサインイン画面を表示する

  • AppDelegate で Firebase と接続
  • Googleアカウントによるログインを実装する場合には追加でおまじないが必要
AppDelegate.swift


import Firebase
import GoogleSignIn

import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    
    // MARK: - UIApplication

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        // Firebase に接続する
        FirebaseApp.configure()
    }
    
    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        
        guard let sourceApplication = options[.sourceApplication] as? String? else { fatalError() }
        
        if FUIAuth.defaultAuthUI()?.handleOpen(url, sourceApplication: sourceApplication) ?? false {
            
            return true
        }
        
        return false
    }

    // 以下略
}
  • 表示元のViewController で Firebase の設定を行う
PresentingViewController.swft

import FirebaseUI

import UIKit


// MARK: - PresentingViewController

class PresentingViewController: UIViewController {


    // MARK: - UIViewController
    
    override func viewDidLoad() {
        
        super.viewDidLoad()
        
        self.setupFirebaseUI()
    }


    // MARK: - Private
    
    private func setupFirebaseUI() {
        
        guard let authUI = FUIAuth.defaultAuthUI() else { fatalError() }

        authUI.providers = [FUIGoogleAuth(authUI: authUI)]       
        authUI.delegate = self
    }
}


// MARK: - FUIAuthDelegate

extension PresentingViewController: FUIAuthDelegate {
    
    func authUI(_ authUI: FUIAuth, didSignInWith authDataResult: AuthDataResult?, error: Error?) {
        
        if let result = authDataResult {
            
            // ログイン成功処理
        }
        else {
            
            // ログイン失敗処理
        }
    }
}
  • Modal 表示する
    • Push 表示はできないため注意
PresentingViewController.swift

    @IBAction private dynamic signInButtonTapped(_ sender: Any?) {
        
        let viewController = authUI.authViewController()
        self.present(viewController, animated: true, completion: nil)
    }

カスタムしたクラスを割り当てる

  • FUIAuthPickerViewController を継承したクラスを作成することでカスタム可能となる
CustomAuthPickerViewController.swift

import FirebaseUI

import UIKit


// MARK: - CustomAuthPickerViewController

class CustomAuthPickerViewController: FUIAuthPickerViewController {
}
  • カスタムしたクラスを割り当てるには FUIAuthDelegate で指定する
PresentingViewController.swift
extension DataSyncViewController: FUIAuthDelegate {

    // 中略
    
    func authPickerViewController(forAuthUI authUI: FUIAuth) -> FUIAuthPickerViewController {
        
        return CustomAuthPickerViewController(authUI: authUI)
    }
}

フルスクリーン表示したい

  • 通常のViewController と同じく modalPresentationStyle をいじる
PresentingViewController.swift

        let viewController = authUI.authViewController()
        viewController.modalPresentationStyle = .fullScreen
        self.present(viewController, animated: true, completion: nil)

キャンセルボタンを非表示にしたい

  • CustomAuthPickerViewControllerauthUI.shouldCancelButton を設定
CustomAuthPickerViewController.swift
class CustomAuthPickerViewController: FUIAuthPickerViewController {

   
    // MARK: - UIViewController
    
    override func viewDidLoad() {
        
        super.viewDidLoad()
        
        self.setupUI()
    }

    

     // MARK: - Private
     
     private func setupUI() {
     
         // キャンセルボタンが消える
         self.authUI.shouldCancelButton = true
     }
}

"Welcome" は "サインイン" にしたい / そもそも NavigationBar は非表示にしたい

  • NavigationBar 関連のUI調整は viewWillAppear のタイミングで行う必要がある
    • viewDidLoad() で設定しても Firebase UI に設定を上書きされる
CustomAuthPickerViewController.swift

    override func viewWillAppear(_ animated: Bool) {
        
        super.viewWillAppear(animated)
        
        // タイトルを "サインイン" に変更
        self.title = "サインイン"
        // NavigationBar を非表示
        self.navigationController?.navigationBar.isHidden = true
    }

サービス選択ボタンに丸みをつけたい

  • ヒエラルキーは以下のようになっている
    • self.view > ScrollView > ContentView > Button
  • ScrollView と ContentView には .subviews[0] でアクセス可能
CustomAuthPickerViewController.swift
    private func setupUI() {
        
        // 各ボタンの UI を変更する
        self.view.subviews[0].subviews[0].subviews[0].subviews.forEach { (view: UIView) in
            
            if let button = view as? UIButton {
                
                button.layer.cornerRadius = 20.0
                button.layer.masksToBounds = true
            }
        }
    }

背景を青色にしたい/背景に画像を表示したい

  • ScrollView、ContentView のそれぞれの背景色を .clear にすることで self.view.backgroundColor の設定が表示されるようになる
CustomAuthPickerViewController.swift
    private func setupUI() {

        let scrollView = self.view.subviews[0]
        scrollView.backgroundColor = .clear
        let contentView = scrollView.subviews[0]
        contentView.backgroundColor = .clear

        // 背景色を変更
        self.view.backgroundColor = .blue
    }
  • 背景イメージを表示するには上記 + self.view.addSubviewUIImageView を追加する
  • 背景イメージを背面に移動させないとボタンが隠れるため注意
CustomAuthPickerViewController.swift
    private func setupUI() {

        let scrollView = self.view.subviews[0]
        scrollView.backgroundColor = .clear
        let contentView = scrollView.subviews[0]
        contentView.backgroundColor = .clear

        // 背景にイメージを追加
        let imageViewframe = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height:UIScreen.main.bounds.height)
        let imageView = UIImageView(frame: imageViewFrame)
        imageView.image = UIImage(named: "myImage")
        imageView.contentMode = .scaleAspectFill
        
        self.view.addSubview(imageView)
        self.view.sendSubviewToBack(imageView)
    }

結果

  • (お洒落かどうかはともかく)サインイン画面をカスタマイズすることができた
カスタム前 カスタム後
Simulator Screen Shot - iPhone SE (iOS 14.2.2nd generation) - 2021-03-03 at 18.16.42.png Simulator Screen Shot - iPhone SE (iOS 14.2.2nd generation) - 2021-03-03 at 17.45.51.png

改善点

  • Storyboard を利用してカスタムする方法を検証
    • より直感的にUIを変更したい
13
11
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
13
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?