- 投稿日:2020-01-16T22:09:14+09:00
【swift5】ストップウォッチタイマーの作り方
キャプチャ
ソース全部
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にも優良な情報があってプログラミングを学びたい人には天国ですね。
(変な情報もたくさんあるのでお気をつけを。)
- 投稿日:2020-01-16T19:46:58+09:00
Mobile Blazor Bindings は「Xamarin.Forms アプリ生成器」でした
BlazorでiOS/Androidネイティブアプリケーションを開発可能にする「Mobile Blazor Bindings」、マイクロソフトが発表 - Publickey
これなんですけど。「ざまりん乙」的な声が今回もチラホラ聞かれたので「マジか!それはすごい」と思って試してみました。
サンプルアプリを動かしてみた
こちらの手順の通りで、簡単に試すことができます。1
まあ、ソリューションを見てみただけで Xamarin(Xamarin.Forms アプリ) なんですけども。
inspect してみた
続いて、Android 向けのプロジェクトをエミュレータで実行し、Android Studio 付属の Device Monitor で inspect してみました(もしかしてガワネイティブ?という可能性もあったので)。
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基盤 ってすごいなあ、と思います。
簡単に動かせたのは Xamarin.Forms アプリ開発環境は既に構築済みだったこともありw ↩
- 投稿日:2020-01-16T18:22:21+09:00
【初心者向け】Showing All Issues "アプリ名" requires a provisioning profile. Select a provisioning profile in the Signing & Capabilities editor.が出た時の対処法。
- 投稿日:2020-01-16T18:21:08+09:00
【初心者向け】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です。
- 投稿日:2020-01-16T17:18:59+09:00
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初学者のため、アドバイスなどいただけると嬉しいです。
- 投稿日:2020-01-16T15:56:28+09:00
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
- ToDo リスト
- ToDoリストを作ってみよう! | FLY-WEST
- 作っていく過程が書いてあり、結構詳しく書いてあるので良いと思います。
- Udemy のおすすめのセクション(購入していれば)
delegate
いろんなアプローチの解説があるので自分に合うものを探しましょう!
- 投稿日:2020-01-16T13:01:36+09:00
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
となるので気をつけましょう。参考
- 投稿日:2020-01-16T12:23:50+09:00
【Swift】Chartsでオシャレなグラフを描画してみる( 棒グラフ編 )
はじめに
Chartsというライブラリはご存知でしょうか?
とても有名なライブラリで、iOSでグラフを描画しようと思ったことがある人なら聞いたことや使ったことがあると思います。Chartsはグラフ自体を非常に細かくカスタマイズすることができる素晴らしいライブラリです✨
今回は忘備録も兼ねてChartsを使って今時でオシャレな棒グラフを作ってみたいと思います。オシャレな棒グラフって?
普段実装ばかりでデザインのことには疎いので、
まずは今時でオシャレな棒グラフのデザインをDribbbleやBehanceで調査してみました。
その結果以下のような棒グラフが流行っているような感じがしました。
Figmaでパパッと作ったので数値などは適当です。
Y軸の値表示なし Y軸の値表示あり ポイントをまとめるとこんな感じになりました。
- X軸の縦線は表示しない
- バーの右上と左上は角丸
- グラフの平均を表す線があって、点線で表示
- Y軸の値を他のラベルなどに表示する場合はグラフに表示しない
4は以下のようなUIの場合、グラフにはY軸の値を表示しない代わりに、グラフをタップするとグラフの上に表示されているラベルにY軸の値が表示されるようなイメージです。
早速作っていきたいところですが、一点問題があります。
棒グラフの角丸はサポートされていない
現在、Chartsでは棒グラフの角丸はサポートされていません。
PRは存在しますが、色々問題があってマージされていない状態です。さすがにフォークして直すのは時間がかかりそうだったので、角丸は省略したものを作成します。
個人的には角丸がなくても結構それっぽくなるので、これはこれでありだと思っています。実際に作ってみる
それでは実際に作っていきます。
Chartsのインストール
ChartsはCocoaPodsとCarthageに対応しています。
自分はCarthageでインストールしました。詳しくは公式のCarthage Installを参考にしてください。BarChartViewを追加する
Chartsのグラフを描画する
ChartView
はInterface Builderに対応しているのでStoryboardから追加することができます。今回は棒グラフを描画したいので一枚
UIView
を用意して、Custom ClassにBarChartView
、ModuleにCharts
を設定します。あとはいつも通りViewControllerにOutlet接続すればコードでいじれるようになります。
import UIKit import Charts class ViewController: UIViewController { @IBOutlet weak var barChartView: BarChartView! // ... }グラフに表示するデータについて
Chartsでは表示するデータを
ChartData
に変換する必要があります。
変換したChartData
をChartView
のもつ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デフォルトの状態でこれを表示するとこんな感じになります。
デフォルト 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)※
LimitLine
はleftAxis
もしくはrightAxis
に対して追加するので、追加する対象のenable
がfalse
になっていると表示されないので注意してください。ここまでで以下のような見た目になりました。だいぶそれっぽくなったと思います。
デフォルト 設定後 棒グラフの色と値の表示の設定
最後に棒グラフの色とグラフの上に値が表示しないように設定します。
これらの設定はChartDataSet
に対して設定します。let dataSet = BarChartDataSet(entries: entries) dataSet.drawValuesEnabled = false dataSet.colors = [.systemBlue]以上で完成です。
最終的にこんな感じになりました。
デフォルト 完成形 さいごに
Chartsで今時でオシャレな棒グラフを作ってみましたがいかがだったでしょうか?
他にもグラフをアニメーションさせたり、ハイライトした時にマーカーを表示できたり、X軸のラベルの表示をカスタマイズできるなど、まだまだカスタマイズできるので気になった方はぜひ試してみてください。公式のサンプルで一通り使い方はマスターできると思います。また、今回作ったグラフはサンプルとしてQiitaChartsSampleにあげてあるので、よければ参考にしてください。
分かりにくい部分や間違いがあれば指摘していただけると嬉しいです?♂️
最後まで読んでいただきありがとうございました。
- 投稿日:2020-01-16T10:06:12+09:00
XcodeでArchiveするとOther items(Generic Xcode Archive)になってしまう原因の探り方
Xcodeからアプリを公開するためにProduct > Archiveを行うと、生成されるファイルがなぜかGeneric Xcode Archiveとなり(iOS App Archiveになることを期待している)OrganizerのOther itemsのカテゴリに振り分けられてしまうという症状に長いこと悩まされていました。
やっと解決することができたので、その方法をここに記そうと思います。
環境
Xcode 11.2.1
注意
筆者はReact Nativeでの開発をメインにやっているため、iOSネイティブのアプリ開発の知識やXcodeに対する知識が豊富ではありません。
この記事の内容自体はSwiftやObj-Cを使ったネイティブでのアプリ開発時にも役に立つと思いますが、念の為ネイティブでのアプリ開発にはそれほど詳しくない人間が書いているという点だけ了承した上でお読みください。。。
ぐぐった
この問題が発生した時にググったところ同じ症状の人をたくさん見つけることができました。
日本語の記事ではこちらの方や
アプリのArchiveでipaが作れなくて焦ったメモ - Qiita
Apple公式のドキュメントにも記載があります。
しかし上記記事たちで触れられている「Skip install」や「Heders」の設定を見ても、自分の場合特に問題がなく途方に暮れておりました。
生成されるGeneric Xcode Archiveの中身を見てみる
正常にiOS App Archiveと認識されるアーカイブとGeneric Xcode Archiveとして認識されてしまうアーカイブの中身を比べてみることに。
アーカイブの中身をみるには、XcodeのWindow > Organizerを開き、対象のアーカイブの上で右クリックをし、
Show in Finderを選択し
アーカイブを右クリックし、パッケージの内容を表示でOKです。
treeコマンド等で正常にアーカイブできる別のアプリと中身を比較してみると、
Productsディレクトリ以下にApplicationsのほか、 usrというディレクトリがあるのが確認できました。(正常なアーカイブには存在しない)
このusrディレクトリを掘っていくと、たくさんのヘッダーファイルが入っていることが確認できました。
これらのファイル名をXcodeのプロジェクト内で検索してみたところ(Command + Shift + Oでファイル検索できます)、特定のライブラリがヒットしました。(今回はSDWebImage)
どうやらSDWebImageのHeaderが怪しいというところまでこれであたりがついたので、SDWebImageを見てみたところ
こんな感じで、先ほどググった時の記事と同じような感じで、HeadersのPublicのところにヘッダーファイルが存在しました。
解決!
という感じで原因を特定しました。
今回原因となっていたSDWebImageは、開発しているアプリが依存しているライブラリが依存しているライブラリだったため、SDWebImageに依存しているライブラリのバージョンをあげて対応しました。(なんでこのバージョンだけこうなっていたのかよくわからんままですが…)
普段からiOSアプリをネイティブで開発している方々にとってはもしかしたら当たり前のことなのかもしれないですが、普段はReact NativeでJSを書いてる身にはなかなか苦しかったのでどなたかの役に立てば幸いです。
- 投稿日:2020-01-16T02:59:25+09:00
(swift)Loafで、サクッとエラーメッセージを表示する
Loafって?
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()引用(スペシャルサンクス)