20200116のiOSに関する記事は10件です。

【swift5】ストップウォッチタイマーの作り方

キャプチャ

スクリーンショット 2020-01-16 21.44.33.png

ソース全部

githubにもアップしております!

https://github.com/sventouz/swift_timer

import UIKit
class ViewController: UIViewController {
    var OurTImer = Timer()
    var TimerDisplayed = 0
    @IBOutlet weak var label: UILabel!
    @IBOutlet weak var start: UIButton!
    @IBOutlet weak var pause: UIButton!
    @IBOutlet weak var reset: UIButton!

    @IBAction func startButton(_ sender: Any) {
        OurTImer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(Action), userInfo: nil, repeats: true)
    }
    @IBAction func pauseButton(_ sender: Any) {
        OurTImer.invalidate()
    }
    @IBAction func resetButton(_ sender: Any) {
        OurTImer.invalidate()
        TimerDisplayed = 0
        label.text = "0"
    }
    @objc func Action() {
        TimerDisplayed += 1
        label.text = String(TimerDisplayed)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

ソースの解説

    var OurTImer = Timer()
    var TimerDisplayed = 0
    @IBOutlet weak var label: UILabel!

Timer()のインスタンス化
TimerDisplayedは秒数を数えてくれている変数
あとは普通の変数

    @IBAction func startButton(_ sender: Any) {
        OurTImer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(Action), userInfo: nil, repeats: true)
    }
    @IBAction func pauseButton(_ sender: Any) {
        OurTImer.invalidate()
    }
    @IBAction func resetButton(_ sender: Any) {
        OurTImer.invalidate()
        TimerDisplayed = 0
        label.text = "0"
    }
    @objc func Action() {
        TimerDisplayed += 1
        label.text = String(TimerDisplayed)
    }

スタートボタンを押した時

startButtonがスタートボタンを押した時の挙動

    @IBAction func startButton(_ sender: Any) {
    }

これ

OurTImer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(Action), userInfo: nil, repeats: true)

//の中の

selector: #selector(Action)

は下で定義しているこれ

    @objc func Action() {
        TimerDisplayed += 1
        label.text = String(TimerDisplayed)
    }
scheduledTimer

で1秒ずつTimerDisplayedが1づつ増えていっている

ポーズボタンを押した時

    @IBAction func pauseButton(_ sender: Any) {
        OurTImer.invalidate()
    }

タイマーを止める処理

リセットボタンを押した時

@IBAction func resetButton(_ sender: Any) {
     OurTImer.invalidate()
     TimerDisplayed = 0
     label.text = "0"
}

タイマーを止める処理をして
表示を0にする

まとめ

これで完成!

参考

https://www.youtube.com/watch?v=z2Jq5U-stag

最近はYoutubeにも優良な情報があってプログラミングを学びたい人には天国ですね。

(変な情報もたくさんあるのでお気をつけを。)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Mobile Blazor Bindings は「Xamarin.Forms アプリ生成器」でした

BlazorでiOS/Androidネイティブアプリケーションを開発可能にする「Mobile Blazor Bindings」、マイクロソフトが発表 - Publickey

これなんですけど。「ざまりん乙」的な声が今回もチラホラ聞かれたので「マジか!それはすごい」と思って試してみました。

サンプルアプリを動かしてみた

こちらの手順の通りで、簡単に試すことができます。1

image.png

まあ、ソリューションを見てみただけで Xamarin(Xamarin.Forms アプリ) なんですけども。

inspect してみた

続いて、Android 向けのプロジェクトをエミュレータで実行し、Android Studio 付属の Device Monitor で inspect してみました(もしかしてガワネイティブ?という可能性もあったので)。

image.png

FrameLayout や RelativeLayout などの Android ネイティブ部品が並んでいるので確かに "ネイティブ" でした。
また、PlatformRenderer とか ButtonRenderer、これらは Xamarin.Forms アプリを inspect した時と同じ感じです。

Mobile Blazor Bindings のソースコードを見てみた

ソースコードはこちらです(Open by default 素晴らしい)。

ここらへん に、それっぽい記述を見つけることができます。

using XF = Xamarin.Forms;

namespace Microsoft.MobileBlazorBindings.Elements
{
    public class Button : View
    {
        static Button()
        {
            ElementHandlerRegistry
                .RegisterElementHandler<Button>(renderer => new ButtonHandler(renderer, new XF.Button()));
        }
(以下略)

サンプルアプリに Razor テンプレート(*.razor) に記述した <Button> という要素は、上記の処理で Xamarin.Forms.Button にマップされるように見えます。

つまり

「Razor の仕組みを使って Xamarin.Forms アプリを作ることができるのが Mobile Blazor Bindings」

ということのようです。 UI用DSLから Android/iOS 向けには Xamarin.Forms が使われる点は、Uno Platform にも近いと思います。

なにがおいしいの?

Blazor は「We B Assembly + Razor」の造語だっと記憶してますが、昨日の .NET Conf Focus on Blazor のまとめを見ると、

「WebAssembly 使う使わん関係なく、とにかく Razor 技術から様々なプラットフォーム向けアプリを生成するフレームワークが Blazor」
という事になったようですね(Mobile Blazor Bindings に wasm 技術の欠片は見当たりませんでした)。

という事で、.razor テンプレートやそれが属するプロジェクトに記述された UI や C# コードは、Webアプリ/モバイルアプリ/デスクトップ向けアプリとしても再利用できますよ、という目論見のようです。

Razor は、ASP.NET を使ってWebフロントエンドを開発するための技術として普及している(と思う)ので、その流れでカバー範囲を広げたい人には刺さるでしょう(一方 XAML を主戦場とする人には前述の Uno Platform の方が刺さるでしょうか)。

「「「ネイティブAndroid のラッパーである Xamarin.Android」、をラップした Xamarin.Forms」をさらにラップした Mobile Blazor Bindings」、、、というゴテゴテ感、個人的にはキライじゃないし、それなりに基盤がしっかりしていないとさすがに崩れ落ちるので、.NET基盤 ってすごいなあ、と思います。


  1. 簡単に動かせたのは Xamarin.Forms アプリ開発環境は既に構築済みだったこともありw 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【初心者向け】Showing All Issues "アプリ名" requires a provisioning profile. Select a provisioning profile in the Signing & Capabilities editor.が出た時の対処法。

解決法

プロビジョニングファイルが設定されていない。
Xcodeのプロジェクトファイルにある、
Signing & Capabilities
→Automatically manage singing
にチェックを入れてTeamの設定をするだけで解決します。
スクリーンショット 2020-01-16 11.37.26.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【初心者向け】Could not launch “アプリ名” Verify the Developer App certificate for your account is trusted on your device. が出た時の対処法。

一番最初にXcodeでRunした時にこのようなエラーが出ることがあり、まとまってる記事がなかったので書きました。

Could not launch “アプリ名”
Verify the Developer App certificate for your account is trusted on your device. Open Settings on “端末名” and navigate to General -> Device Management, then select your Developer App certificate to trust it.
Internal launch error: process launch failed: Security

解決法

インストール先の端末で設定を追加する。

  • iOS12
    一般→プロファイルとデバイス管理→デベロッパAppを選択→信頼を選択

  • iOS13
    一般→デバイス管理→デベロッパAppを選択→信頼を選択

※スクショはiOS12です。

「一般」を選択
1-2.png

「プロファイルとデバイス管理」を選択
2-2.png

「デベロッパAppを選択」を選択
3-2.png

「信頼」を選択
4-2.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

flutter 全面にローディングを表示させるサンプル

実現したいこと

なにか処理中で、操作を受け付けれないような状態の時に、
全画面でローディングを表示させるやりかたについて書きたいと思います。

動作の様子

ボタンを押すとローディングが表示。2秒後に自動的に閉じます。

動作コード

こちらに一式用意しています。
https://github.com/quqjp/flutter-test

コード箇所はこちら。
https://github.com/quqjp/flutter-test/tree/master/lib/sample1

構成

ローディング表示のWidget OverlayLoadingMolecules を作成。

組み込む側メインのコードにて、Stack Widget を用いて最前面に配置します。

ローディングWidget OverlayLoadingMolecules

表示の状態 visible プロパティを持ち表示を外部から制御できるようになっています。
非表示時は、空のContainer()が表示されます。
くるくるローディング表示自体は、CircularProgressIndicator Widget を用いた。

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

//
// 全面表示のローディング
//
class OverlayLoadingMolecules extends StatelessWidget {
  OverlayLoadingMolecules({@required this.visible});

  //表示状態
  final bool visible;

  @override
  Widget build(BuildContext context) {
    return visible
        ? Container(
            decoration: new BoxDecoration(
              color: Color.fromRGBO(0, 0, 0, 0.6),
            ),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                CircularProgressIndicator(
                    valueColor: new AlwaysStoppedAnimation<Color>(Colors.white))
              ],
            ),
          )
        : Container();
  }
}

組み込む側メインのコード

//dart package
import 'package:flutter/material.dart';

//third party package

//my package

//same package
import "overlay_loading_molecules.dart";

//
// 全面にローディングを表示させるサンプル
//
class Sample1Page extends StatefulWidget {
  Sample1Page({Key key, this.title}) : super(key: key);

  // タイトル
  final String title;

  @override
  _State createState() => _State();
}

class _State extends State<Sample1Page> {
  //ローディング表示の状態
  bool visibleLoading = false;

  @override
  void initState() {
    super.initState();
  }

  //
  //
  // ボタンハンドラ
  onPressMyButton() async {
    //ローディングを表示
    setState(() {
      visibleLoading = true;
    });

    //2秒待つ
    await Future.delayed(const Duration(milliseconds: 2000), () {});

    //ローディングを非表示
    setState(() {
      visibleLoading = false;
    });
  }

  ///
  ///
  ///
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      //
      body: ClipRect(
        child: Stack(
          fit: StackFit.expand,
          overflow: Overflow.clip,
          children: <Widget>[
            Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                //
                //ローディングを表示させるためのボタン
                RaisedButton(
                  onPressed: onPressMyButton,
                  child: Text('ローディングを表示', style: TextStyle(fontSize: 20)),
                ),
              ],
            ),
            //
            //ローディング
            OverlayLoadingMolecules(visible: visibleLoading)
          ],
        ),
      ),
    );
  }
}

まとめ

flutter で全面にローディングを表示させる方法をまとめました。
flutter初学者のため、アドバイスなどいただけると嬉しいです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

TableView と delegate を理解する(したい)

対象

Swift 初心者向け🐤
参考資料程度に呼んでください!

どんなときに読むの?

TableView と delegate にハマったとき。
TableView 難しいよ〜 となったとき。

TableView と delegate のはまりどころ

  • 更新されない
    • tableView.reloadData() を呼んでいない
    • 配列に追加した後に、tableView.reloadData() を呼んでいない
  • 表示されない
    • tableView.dataSource = self 書いていない.
    • numberOfInSection で return 0 になっている
    • class 〇〇ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate にしていない
  • アプリが落ちた
    • cell の名前を確認。間違ってないか
    • tableView.register で cell を登録しているか
    • 配列の範囲外(配列の要素数)の外にアクセスしているか
    • ( 配列は、0, 1, 2, 3... と数が増える。 )
  • cell をタップしても反応しない
    • tableView.delegate = self を書いていない
    • class 〇〇ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate にしていない
    • didSelectRowAt を呼んでない
  • エラーが消えない
    • class 〇〇ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate にしていない

参考になる資料

TableView

delegate

いろんなアプローチの解説があるので自分に合うものを探しましょう!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

App Store Connect の Missing Compliance をなくす方法

問題

TestFlight配信するために IPAファイルをApp Store Connectへアーカイブしているのですが、アーカイブ後の処理(長い)が終わったあとで毎回「Missing Compliance」というワーニングがでて、毎度アーカイブ後にApp Store Connect開いて対処する必要がありました。

Missing Complianceとは

これが何のかというと、独自の暗号方式を利用している場合は適切なドキュメントを提出する必要がありますよ、という話で、独自の暗号化しないならNOを選ぶという事になると思います。それなら毎回聞かれたくないですよね。

方法

Info.plist に 下記を加えるだけです。

<key>ITSAppUsesNonExemptEncryption</key>
<false/>

Xcodeからの追加だと、Keyの名前は App Uses Non-Exempt Encryptionとなるので気をつけましょう。

参考

https://stackoverflow.com/a/35842359/6891441

https://developer.apple.com/documentation/bundleresources/information_property_list/itsappusesnonexemptencryption

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift】Chartsでオシャレなグラフを描画してみる( 棒グラフ編 )

はじめに

Chartsというライブラリはご存知でしょうか?
とても有名なライブラリで、iOSでグラフを描画しようと思ったことがある人なら聞いたことや使ったことがあると思います。

Chartsはグラフ自体を非常に細かくカスタマイズすることができる素晴らしいライブラリです✨
今回は忘備録も兼ねてChartsを使って今時でオシャレな棒グラフを作ってみたいと思います。

オシャレな棒グラフって?

普段実装ばかりでデザインのことには疎いので、
まずは今時でオシャレな棒グラフのデザインをDribbbleBehanceで調査してみました。
その結果以下のような棒グラフが流行っているような感じがしました。
Figmaでパパッと作ったので数値などは適当です。

Y軸の値表示なし Y軸の値表示あり
Bar chart ( disable grid ).png Bar chart ( enable grid ).png

ポイントをまとめるとこんな感じになりました。

  1. X軸の縦線は表示しない
  2. バーの右上と左上は角丸
  3. グラフの平均を表す線があって、点線で表示
  4. Y軸の値を他のラベルなどに表示する場合はグラフに表示しない

4は以下のようなUIの場合、グラフにはY軸の値を表示しない代わりに、グラフをタップするとグラフの上に表示されているラベルにY軸の値が表示されるようなイメージです。

スクリーンショット 2020-01-14 15.29.01.png

早速作っていきたいところですが、一点問題があります。

棒グラフの角丸はサポートされていない

現在、Chartsでは棒グラフの角丸はサポートされていません。
PRは存在しますが、色々問題があってマージされていない状態です。

さすがにフォークして直すのは時間がかかりそうだったので、角丸は省略したものを作成します。
個人的には角丸がなくても結構それっぽくなるので、これはこれでありだと思っています。

実際に作ってみる

それでは実際に作っていきます。

Chartsのインストール

ChartsはCocoaPodsとCarthageに対応しています。
自分はCarthageでインストールしました。詳しくは公式のCarthage Installを参考にしてください。

BarChartViewを追加する

Chartsのグラフを描画するChartViewInterface Builderに対応しているのでStoryboardから追加することができます。

今回は棒グラフを描画したいので一枚UIViewを用意して、Custom ClassBarChartViewModuleChartsを設定します。

スクリーンショット 2020-01-15 16.12.09.png

あとはいつも通りViewControllerにOutlet接続すればコードでいじれるようになります。

import UIKit
import Charts

class ViewController: UIViewController {

    @IBOutlet weak var barChartView: BarChartView!

    // ...
}

グラフに表示するデータについて

Chartsでは表示するデータをChartDataに変換する必要があります。
変換したChartDataChartViewのもつdataプロパティにセットすることでデータが描画されます。
以下では適当なIntの配列をBarChartDataに変換してグラフに表示しています。

let rawData: [Int] = [20, 50, 70, 30, 60, 90, 40]
let entries = rawData.enumerated().map { BarChartDataEntry(x: Double($0.offset), y: Double($0.element)) }
let dataSet = BarChartDataSet(entries: entries)
let data = BarChartData(dataSet: dataSet)
barChartView.data = data

デフォルトの状態でこれを表示するとこんな感じになります。

デフォルト
スクリーンショット 2020-01-15 16.26.26.png

X座標軸の設定

X座標軸関連の設定はxAxisプロパティに対して設定します。
デフォルトの状態では余分な線などが表示されていたりするので、X軸のラベルの位置、軸の線の表示、グリッドの非表示を行っています。

// X軸のラベルの位置を下に設定
barChartView.xAxis.labelPosition = .bottom
// X軸のラベルの色を設定
barChartView.xAxis.labelTextColor = .systemGray
// X軸の線、グリッドを非表示にする
barChartView.xAxis.drawGridLinesEnabled = false
barChartView.xAxis.drawAxisLineEnabled = false

右側のY座標軸の設定

Y座標軸は左右それぞれ設定することができます。
右側のY座標軸関連の設定はrightAxisプロパティに設定します。
今回は右側のY座標軸は表示しないので無効にします。

// 右側のY座標軸は非表示にする
barChartView.rightAxis.enabled = false

左側のY座標軸の設定

左側のY座標軸関連の設定はleftAxisプロパティに設定します。
ここはY軸の値を表示するかしないかで変わってきますが、とりあえずY軸の値を表示したパターンを作成します。

デフォルトではY座標の最小値がグラフに表示しているデータによって決定されてしまうので、axisMinimumに0を設定して0始まりになるように設定したり、ラベルの色や数、グリッドや軸線の表示に関する設定をしています。

// Y座標の値が0始まりになるように設定
barChartView.leftAxis.axisMinimum = 0.0
barChartView.leftAxis.drawZeroLineEnabled = true
barChartView.leftAxis.zeroLineColor = .systemGray
// ラベルの数を設定
barChartView.leftAxis.labelCount = 5
// ラベルの色を設定
barChartView.leftAxis.labelTextColor = .systemGray
// グリッドの色を設定
barChartView.leftAxis.gridColor = .systemGray
// 軸線は非表示にする
barChartView.leftAxis.drawAxisLineEnabled = false

凡例の設定

デフォルトではグラフの凡例が表示されているので非表示にします。

barChartView.legend.enabled = false

平均の線の設定

平均の線はLimitLineを使って表示します。
以下では線の色と点線の設定を行っています。lineDashLengthsは複数の値を入れることで不規則な形の点線を作ることも可能です。

let avg = rawData.reduce(0) { return $0 + $1 } / rawData.count
let limitLine = ChartLimitLine(limit: Double(avg))
limitLine.lineColor = .systemOrange
limitLine.lineDashLengths = [4]
barChartView.leftAxis.addLimitLine(limitLine)

LimitLineleftAxisもしくはrightAxisに対して追加するので、追加する対象のenablefalseになっていると表示されないので注意してください。

ここまでで以下のような見た目になりました。だいぶそれっぽくなったと思います。

デフォルト 設定後
スクリーンショット 2020-01-15 16.26.26.png スクリーンショット 2020-01-16 10.04.58.png

棒グラフの色と値の表示の設定

最後に棒グラフの色とグラフの上に値が表示しないように設定します。
これらの設定はChartDataSetに対して設定します。

let dataSet = BarChartDataSet(entries: entries)
dataSet.drawValuesEnabled = false
dataSet.colors = [.systemBlue]

以上で完成です。
最終的にこんな感じになりました。

デフォルト 完成形
スクリーンショット 2020-01-15 16.26.26.png スクリーンショット 2020-01-16 10.26.29.png

さいごに

Chartsで今時でオシャレな棒グラフを作ってみましたがいかがだったでしょうか?
他にもグラフをアニメーションさせたり、ハイライトした時にマーカーを表示できたり、X軸のラベルの表示をカスタマイズできるなど、まだまだカスタマイズできるので気になった方はぜひ試してみてください。公式のサンプルで一通り使い方はマスターできると思います。

また、今回作ったグラフはサンプルとしてQiitaChartsSampleにあげてあるので、よければ参考にしてください。

分かりにくい部分や間違いがあれば指摘していただけると嬉しいです🙇‍♂️
最後まで読んでいただきありがとうございました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

XcodeでArchiveするとOther items(Generic Xcode Archive)になってしまう原因の探り方

Xcodeからアプリを公開するためにProduct > Archiveを行うと、生成されるファイルがなぜかGeneric Xcode Archiveとなり(iOS App Archiveになることを期待している)OrganizerのOther itemsのカテゴリに振り分けられてしまうという症状に長いこと悩まされていました。

スクリーンショット 2020-01-16 9.36.00.png

やっと解決することができたので、その方法をここに記そうと思います。

環境

Xcode 11.2.1

注意

筆者はReact Nativeでの開発をメインにやっているため、iOSネイティブのアプリ開発の知識やXcodeに対する知識が豊富ではありません。

この記事の内容自体はSwiftやObj-Cを使ったネイティブでのアプリ開発時にも役に立つと思いますが、念の為ネイティブでのアプリ開発にはそれほど詳しくない人間が書いているという点だけ了承した上でお読みください。。。

ぐぐった

この問題が発生した時にググったところ同じ症状の人をたくさん見つけることができました。

日本語の記事ではこちらの方や

アプリのArchiveでipaが作れなくて焦ったメモ - Qiita

Apple公式のドキュメントにも記載があります。

https://developer.apple.com/library/archive/technotes/tn2215/_index.html#//apple_ref/doc/uid/DTS40011221-CH1-PROJ

しかし上記記事たちで触れられている「Skip install」や「Heders」の設定を見ても、自分の場合特に問題がなく途方に暮れておりました。

生成されるGeneric Xcode Archiveの中身を見てみる

正常にiOS App Archiveと認識されるアーカイブとGeneric Xcode Archiveとして認識されてしまうアーカイブの中身を比べてみることに。

アーカイブの中身をみるには、XcodeのWindow > Organizerを開き、対象のアーカイブの上で右クリックをし、

スクリーンショット 2020-01-16 9.49.07.png

Show in Finderを選択し

スクリーンショット 2020-01-16 9.49.19.png

アーカイブを右クリックし、パッケージの内容を表示でOKです。

treeコマンド等で正常にアーカイブできる別のアプリと中身を比較してみると、

スクリーンショット 2020-01-16 9.53.47.png

Productsディレクトリ以下にApplicationsのほか、 usrというディレクトリがあるのが確認できました。(正常なアーカイブには存在しない)

このusrディレクトリを掘っていくと、たくさんのヘッダーファイルが入っていることが確認できました。

image.png

これらのファイル名をXcodeのプロジェクト内で検索してみたところ(Command + Shift + Oでファイル検索できます)、特定のライブラリがヒットしました。(今回はSDWebImage)

image.png

どうやらSDWebImageのHeaderが怪しいというところまでこれであたりがついたので、SDWebImageを見てみたところ

image.png

こんな感じで、先ほどググった時の記事と同じような感じで、HeadersのPublicのところにヘッダーファイルが存在しました。

解決!

という感じで原因を特定しました。

今回原因となっていたSDWebImageは、開発しているアプリが依存しているライブラリが依存しているライブラリだったため、SDWebImageに依存しているライブラリのバージョンをあげて対応しました。(なんでこのバージョンだけこうなっていたのかよくわからんままですが…)


普段からiOSアプリをネイティブで開発している方々にとってはもしかしたら当たり前のことなのかもしれないですが、普段はReact NativeでJSを書いてる身にはなかなか苦しかったのでどなたかの役に立てば幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

(swift)Loafで、サクッとエラーメッセージを表示する

Loafって?

(実装例)
20200116_021428.GIF

Inspired by Android's Toast,
Loaf is a Swifty Framework for Easy iOS Toasts
(引用: https://github.com/schmidyy/Loaf)

つまり、
ios版のAndroid's Toastのようです。

ちなみに、Android's Toastとは、以下です。

トーストは、操作に関する簡単なフィードバックを小さなポップアップに表示します。 トーストでは、メッセージの表示に必要なスペースのみを使用します。現在のアクティビティは表示されたままになり、引き続き操作することができます。トーストはタイムアウト後に自動的に消えます。
(引用: https://developer.android.com/guide/topics/ui/notifiers/toasts?hl=ja)!

Loafを使うことで、超カンタンにエラーメッセージやアラートなどを実装することができます。

Loafの使い方

Cocoapods
まず、pod 'Loaf'を追加して、pod installしてください。

そして、以下のコードを記述してください。

Loaf("メッセージを表示", sender: self).show()

以上です。(カンタンスギ)

応用

スタイルをカスタマイズする(実装例)

//アイコンのイメージを指定する(今回は、postクラスのphoto(UIImage)を使用しました。)
let image = self.post.photo

Loaf("\(self.post.name)のポストを編集しました。", 
      //.customを指定し、背景色にsystemGreenとアイコンにimageを指定する
      state: .custom(.init(backgroundColor: .systemGreen, icon: image)), 
      location: .top, presentingDirection: .vertical, dismissingDirection: .vertical, sender: self).show()

実行結果↓
20200116_021515.GIF

引用(スペシャルサンクス)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む