- 投稿日:2020-11-20T16:45:19+09:00
Xamarin.FormsにてiOSのビルドエラー。画像がFile not foundとされる問題
以下の問題が発生していましたが解決したので記録しておきます。
同じような問題を抱える開発者もいると思うので参考になれば幸いです。問題
以下のビルドエラーがでる
File not found: ~/Library/Caches/Xamarin/mtbs/builds/~/AppIcon.appiconset/[画像ファイル名].png
前提
- Microsoft Visual Studio 2019 を使用
- iOS ビルド時にエラー
- Macbookの容量がないなどの理由でLibrary/Caches/内の削除など行った
- AppIcons.appiconsetで設定している
原因
iOSのプロジェクトファイルにすでに使用されていないAssetの参照先が残っていた。
Macbook内のLibrary/Cachesフォルダ内に対象のファイルが存在しないためエラーを起こしていた。解決策
iOSのプロジェクトファイルにすでに使用されていないAssetの参照先を削除する。
ProjectName.iOS.csproj<ItemGroup> <ImageAsset Include="Assets.xcassets\AppIcon.appiconset\appstore.png"> <!-- AppIconsではなくAppIconなど、以前設定していたパスが残っている(この部分を削除) --> <Visible>false</Visible> </ImageAsset> <!-- (略) --> <ImageAsset Include="Assets.xcassets\AppIcons.appiconset\appstore.png"> <!-- 以下は現在使用している正しいパス --> <Visible>false</Visible> </ImageAsset> <ImageAsset Include="Assets.xcassets\AppIcons.appiconset\Contents.json"> <Visible>false</Visible> </ImageAsset> <ImageAsset Include="Assets.xcassets\AppIcons.appiconset\icon120.png"> <Visible>false</Visible> </ImageAsset> <ImageAsset Include="Assets.xcassets\AppIcons.appiconset\icon152.png"> <Visible>false</Visible> </ImageAsset> <ImageAsset Include="Assets.xcassets\AppIcons.appiconset\icon167.png"> <Visible>false</Visible> </ImageAsset> <!-- (略) --> </ItemGroup>結論
iOSのプロジェクトファイル内は普通は編集することはないはずでバグの一種で設定が残っていたと思われる。(改善されている可能性もある)
MacbookのLibrary/Caches/内の削除前は問題なくビルドが通っていたので削除を行ったことでエラーが表面化したと思われます。
以上、同様の問題で参考になれば幸いです。
- 投稿日:2020-11-20T15:11:23+09:00
[iOS・Swift] iPhoneからjsonデータを取得する方法
はじめに
Swiftでjsonファイルを取り出す過程で詰まるポイントがありましたので、共有したいと思います。
①jsonファイルを作成するまで
Export Json Fileというボタンを押して、jsonファイルを吐き出すようにしました。
※Simulatorではなく、実機で動かしています②jsonファイルをXcodeからダウンロードする
Devices and Simulatorsから作成したアプリケーションを選択します。
選択後、以下のような歯車ボタンからDownload Containerを開きます。
ダウンロード後、Finderよりダウンロードファイル(ex. com.kamimura.HealthKitDataCollection 2020-11-20 14/46.13.735.xcappdata)からパッケージの内容を表示で開きます。
その後、AppData -> Documents -> output.jsonで作成したjsonファイルが存在しております。
※ファイルの存在場所は、この限りではありませんのでご注意ください!
本アプリのGithub (https://github.com/Ryosukekamimura/HealthKit_Data_Collection)
最後まで読んでいただき、ありがとうございます。
誰かのためになれば、幸いです!
- 投稿日:2020-11-20T11:06:24+09:00
プログラミング超初心者がFlutterの環境構築をしてみた
やったこと
KBOYさんのYouTubeを見ながら、Flutterの環境構築をしました。1、Flutterのインストール
2、Flutterのパスを通す2からすでに、苦戦するという「マジか」と思いつつなんとかできました。
.bash_profile にパスを記載しようとしたのですが、
最近のPCは bash ではなく.zshrc っていうのが最近の新しいパス設定の場所らしい
参考にした動画
https://www.youtube.com/watch?v=kpvVENfDCRc&list=PLuLRJz1UnJzE4-HlkLTG8ARbZ2TDBNHzZ
- 投稿日:2020-11-20T10:38:00+09:00
[Swift5]storyboardとコードでNavigationBarをカスタムする方法
なぜstoryboardだけでやらない?
Swiftで開発を進める際に、storyboardでUIを構築するか、コードのみでUIを構築するか初学者の方は悩まれるのでは?と私は思います。
storyboardのみで開発しても良いのですが、コードでカスタムした方が作業工数を減らせることや、デザインの変更などが必要な場合に、コードの方が編集しやすい点などからコードでカスタムを行います。しかし、コードのみだと画面遷移などが直感的に理解しずらいので、今回は最低限をstoryboardで構築し、カスタム内容はコードで記述します。
その他にも、storyboardのみで構築するとコンフリクトが発生しやすい問題や、コードのみで構築するとコードの記述量が多くなるなど双方にメリット,デメリットが存在します。
storyboardでNavigartionControllerの実装
まずstoryboardでNavigationBarを用意します。
①storyboardのiPhoneを選択(下記画像中央)
②Xcodeのメニューバー(Mac液晶最上部)から
/Editor/Embed In/NavigationController/
を選択③すると下記画像のように
NavigationControllerを継承したViewController
が作成される。
これでstoryboardによるNavigationBarの準備が整いました。コードのよるNavigationBarのカスタム
NavigationBarのカスタムをコードでおこないます。今回カスタムするのは以下の通り。
① NavigationBarの色 ② NavigationBarのtitle ③ NavigationBarのtitleの文字色 ④ NavigationBarのtitleのフォントとサイズ ⑤ すりガラスのような状態をfalseに ⑥ NavigationBarの下線を消すそれではコードを記述します。
ViewController.swiftclass ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() //NavigationBarのtitleとその色とフォント navigationItem.title = "サンプル文字列" self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 20.0)] //NavigationBarの色 self.navigationController?.navigationBar.barTintColor = UIColor.red //一部NavigationBarがすりガラス?のような感じになるのでfalseを指定 self.navigationController?.navigationBar.isTranslucent = false //NavigationBarの下線を消す navigationController?.navigationBar.setValue(true, forKey: "hidesShadow") } }ビルドすると下記画像の通りNavigationBarのデザインが変更されたのが確認できます!
//一部NavigationBarがすりガラス?のような感じになるのでfalseを指定 self.navigationController?.navigationBar.isTranslucent = false
//一部NavigationBarがすりガラス?のような感じになるのでfalseを指定
に関しては、
false
を指定しない場合、想定外のカラーになるので記述。実際に自身で色やフォントサイズをアレンジしてみると学びが深まると思いますのでぜひ!
最後に
冒頭でも述べましたが、storyboardでのUI構築とコードのみでのUI構築の双方にメリット&デメリットが存在するので、互いの特徴を理解して扱っていく必要がありますね!
最後までご覧いただきありがとうございます!
ぜひ参考にしてください。
- 投稿日:2020-11-20T05:46:55+09:00
Metal で サポートしている GPU family と feature set を調べる
M1 Mac mini がやってきた
我が家に M1 Chip の Mac mini がやってきました。これまで、Metal の試行錯誤は、Intel Mac の Simulator と 実際の iPhone や iPad でサポートしている機能が違うので、試行錯誤の効率が悪かったのですが、M1 Chip Mac を入手したので、A12相当の機能の試行錯誤などの効率があがるものと期待していました。しかし、M1 Chip の Mac の Simulator で検証コードを動かすと、思いもよらぬところで落ちました。
「あれ?」と思い、iPad Pro で実行すると、落ちません。そこで、色々調べ始めると、M1 Chip + Big Sur + Xcode 12.2 のシミュレータでは、A8相当にしかならない事に気がつきました。そこで、2020年10月21日つまり比較的最近アップデートされた、Metal Feature Set Tables を調べてみても、M1 の記述が全くありません。
Metal Feature Set Tables
Appleの公式ドキュメントはこれです。
https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf
iOS, macOSの実行環境は結構組み合わせが多い
よくよく考えると、macOS, iOS で動作するアプリの環境は様々です。
- iOS native on A chip
- iOS simulator on Intel Mac
- iOS simulator on M chip
- macOS native on Intel Mac
- macOS native on M chip
- macCatalyst on Intel Mac
- macCatalyst on M chip
例えば最終的な実行環境はA chipのみを対象としていても、開発工程で simulator などを使うと効率が上がる場合があります。Metal で試行錯誤を繰り返すには、どの機能がどの環境で動作するのか明確にする必要があると思いました。
MetalFeatureQuery
そこで、簡単にテストできるプロジェクトを作ってみました。上記の組み合わせで動作する筈ですが、まだ全てで試した訳ではありません。
https://github.com/codelynx/MetalFeatureQuery
環境
執筆時点の環境は以下の通りです。
Apple Swift version 5.3.1 (swiftlang-1200.0.41 clang-1200.0.32.8) Target: arm64-apple-darwin20.1.0Xcode Version 12.2 (12B45b)
macOS Big Sur 11.0.1 (20B29)License
MIT License
- 投稿日:2020-11-20T01:35:10+09:00
【SwiftUI】経過時間の表示とListViewのセルデザイン
はじめに
SwiftUIでRelativeDateTimeFormatterクラスを用いて、経過時間を取得できるようにすることと、取得した経過時間を表示することを目的とする。
UIのデザインはcakesのnote風のデザインを参考にカード型のViewを作ります。
今後は今回作成したカードに前回までに実装した地図と都道府県市町村名を表示できるようにし、Firebaseで更新できるようにすることが目的です。
前回までの記事は以下を参考ください。参考記事
【SwiftUI】Mapkitから取得した情報をFirebaseに保存する開発環境
OSX 10.15.7 (Catalina)
Xcode 12.2.0
CocoaPods 1.10.0RelativeDateTimeFormatterの実装
基準日時からの経過時間を出力するクラスです。Twitterなどの○秒前や○日前などを表示をすることができます。
ロケーションを設定することで英語表記や日本語表記に変更が可能になります。
以下では○秒前、○分前、○時間前、○日前、○年前をそれぞれ記載しています。参考記事
How to show a relative date and time using RelativeDateTimeFormatter
Relative date time formatting in SwiftUIimport SwiftUI let nowTime = Date() print(nowTime) let formatter = RelativeDateTimeFormatter() formatter.locale = Locale(identifier: "ja_JP") let fmt = ISO8601DateFormatter() // ○秒前 let createdDate = "2020-11-19T16:12:30+0000" print(createdDate) let date1 = fmt.date(from: createdDate)! let components = Calendar.current.dateComponents( [.day, .year, .month, .minute, .second], from: Date(), to: date1 ) let timeAgo1 = formatter.localizedString(from: components) print(timeAgo1) // ○分前 let createdDate2 = "2020-11-19T16:00:00+0000" print(createdDate2) let date2 = fmt.date(from: createdDate2)! let components2 = Calendar.current.dateComponents( [.day, .year, .month, .minute, .second], from: Date(), to: date2 ) let timeAgo2 = formatter.localizedString(from: components2) print(timeAgo2) // ○時間前 let createdDate3 = "2020-11-19T11:00:00+0000" print(createdDate3) let date3 = fmt.date(from: createdDate3)! let components3 = Calendar.current.dateComponents( [.day, .year, .month,.hour ,.minute, .second], from: Date(), to: date3 ) let timeAgo3 = formatter.localizedString(from: components3) print(timeAgo3) // ○日前 let createdDate4 = "2020-11-15T11:00:00+0000" print(createdDate4) let date4 = fmt.date(from: createdDate4)! let components4 = Calendar.current.dateComponents( [.year, .month, .day, .hour , .minute, .second], from: Date(), to: date4 ) let timeAgo4 = formatter.localizedString(from: components4) print(timeAgo4) // ○年前 let createdDate5 = "2000-11-15T11:00:00+0000" print(createdDate4) let date5 = fmt.date(from: createdDate5)! let components5 = Calendar.current.dateComponents( [.year, .month, .day, .hour , .minute, .second], from: Date(), to: date5 ) let timeAgo5 = formatter.localizedString(from: components5) print(timeAgo5)playgroundで出力した結果は以下のとおりです。
2020-11-19 16:12:35 +0000 2020-11-19T16:12:30+0000 5 秒前 2020-11-19T16:00:00+0000 12 分前 2020-11-19T11:00:00+0000 5 時間前 2020-11-15T11:00:00+0000 4 日前 2020-11-15T11:00:00+0000 20 年前
経過時間は自動で切り替えて表示されます。
RelativeDateTimeFormatterを実装し、経過時間を表示したカードを作る。
手順は以下のとおりです。
1. 地図、タイトル、作者、日時などを表示したカード型のViewをつくる
2. リストに先ほど作成したカードを表示LocationRow.swiftimport SwiftUI struct ContentView: View { var user = "松尾芭蕉" var userImage = "basho" var haiku = "古池や 蛙飛びこむ 水の音" var mapImage = "mapImage" var place = "東京都江東区" static let formatter = RelativeDateTimeFormatter() var body: some View { // ○秒、○日、○年前を表示 let createdDate = "1686-01-01T12:00:00+0009" ContentView.formatter.locale = Locale(identifier: "ja_JP") let fmt = ISO8601DateFormatter() let date1 = fmt.date(from: createdDate)! let components = Calendar.current.dateComponents( [.day, .year, .month, .minute, .second], from: Date(), to: date1 ) let timeAgo = ContentView.formatter.localizedString(from: components) return VStack { VStack { Image(mapImage) .resizable() .aspectRatio(contentMode: .fit) .cornerRadius(12.0, antialiased: /*@START_MENU_TOKEN@*/true/*@END_MENU_TOKEN@*/) HStack { Spacer() Text(place).font(.caption).foregroundColor(.gray) .padding(.bottom, 5) } } Text(haiku).font(.title3).fontWeight(.bold) HStack { Image(systemName: "heart").font(.headline).foregroundColor(Color("pinkColor")) Text("225").font(.headline).foregroundColor(Color("pinkColor")) Spacer() }.padding(.top, 5) HStack { Image(userImage) .resizable() .frame(width: 30, height: 30) .clipShape(Circle()) HStack { Text(user).font(.headline).fontWeight(.light) + Text("・").font(.headline).fontWeight(.light) + Text(timeAgo).font(.headline).fontWeight(.light) } Spacer() HStack { Image(systemName: "text.bubble").font(.title).foregroundColor(.gray) Image(systemName: "heart.fill").font(.title).foregroundColor(Color("pinkColor")) } } }.padding() } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() .previewLayout(.fixed(width: 414, height: 391)) } }今後は今回作成したカードをリストにし、表示できるようにします。
以上です。
- 投稿日:2020-11-20T01:35:10+09:00
【SwiftUi】RelativeDateTimeFormatterクラス実装とListViewのセルデザイン
はじめに
SwiftUIでRelativeDateTimeFormatterクラスを用いて、経過時間を取得できるようにすることと、取得した経過時間を表示することを目的とする。
UIのデザインはcakesのnote風のデザインを参考にカード型のViewを作ります。
今後は今回作成したカードに前回までに実装した地図と都道府県市町村名を表示できるようにし、Firebaseで更新できるようにすることが目的です。
前回までの記事は以下を参考ください。参考記事
【SwiftUI】Mapkitから取得した情報をFirebaseに保存する開発環境
OSX 10.15.7 (Catalina)
Xcode 12.2.0
CocoaPods 1.10.0RelativeDateTimeFormatterの実装
基準日時からの経過時間を出力するクラスです。Twitterなどの○秒前や○日前などを表示をすることができます。
ロケーションを設定することで英語表記や日本語表記に変更が可能になります。
以下では○秒前、○分前、○時間前、○日前、○年前をそれぞれ記載しています。参考記事
How to show a relative date and time using RelativeDateTimeFormatter
Relative date time formatting in SwiftUIimport SwiftUI let nowTime = Date() print(nowTime) let formatter = RelativeDateTimeFormatter() formatter.locale = Locale(identifier: "ja_JP") let fmt = ISO8601DateFormatter() // ○秒前 let createdDate = "2020-11-19T16:12:30+0000" print(createdDate) let date1 = fmt.date(from: createdDate)! let components = Calendar.current.dateComponents( [.day, .year, .month, .minute, .second], from: Date(), to: date1 ) let timeAgo1 = formatter.localizedString(from: components) print(timeAgo1) // ○分前 let createdDate2 = "2020-11-19T16:00:00+0000" print(createdDate2) let date2 = fmt.date(from: createdDate2)! let components2 = Calendar.current.dateComponents( [.day, .year, .month, .minute, .second], from: Date(), to: date2 ) let timeAgo2 = formatter.localizedString(from: components2) print(timeAgo2) // ○時間前 let createdDate3 = "2020-11-19T11:00:00+0000" print(createdDate3) let date3 = fmt.date(from: createdDate3)! let components3 = Calendar.current.dateComponents( [.day, .year, .month,.hour ,.minute, .second], from: Date(), to: date3 ) let timeAgo3 = formatter.localizedString(from: components3) print(timeAgo3) // ○日前 let createdDate4 = "2020-11-15T11:00:00+0000" print(createdDate4) let date4 = fmt.date(from: createdDate4)! let components4 = Calendar.current.dateComponents( [.year, .month, .day, .hour , .minute, .second], from: Date(), to: date4 ) let timeAgo4 = formatter.localizedString(from: components4) print(timeAgo4) // ○年前 let createdDate5 = "2000-11-15T11:00:00+0000" print(createdDate4) let date5 = fmt.date(from: createdDate5)! let components5 = Calendar.current.dateComponents( [.year, .month, .day, .hour , .minute, .second], from: Date(), to: date5 ) let timeAgo5 = formatter.localizedString(from: components5) print(timeAgo5)playgroundで出力した結果は以下のとおりです。
2020-11-19 16:12:35 +0000 2020-11-19T16:12:30+0000 5 秒前 2020-11-19T16:00:00+0000 12 分前 2020-11-19T11:00:00+0000 5 時間前 2020-11-15T11:00:00+0000 4 日前 2020-11-15T11:00:00+0000 20 年前
経過時間は自動で切り替えて表示されます。
RelativeDateTimeFormatterを実装し、経過時間を表示したカードを作る。
手順は以下のとおりです。
1. 地図、タイトル、作者、日時などを表示したカード型のViewをつくる
2. リストに先ほど作成したカードを表示LocationRow.swiftimport SwiftUI struct ContentView: View { var user = "松尾芭蕉" var userImage = "basho" var haiku = "古池や 蛙飛びこむ 水の音" var mapImage = "mapImage" var place = "東京都江東区" static let formatter = RelativeDateTimeFormatter() var body: some View { // ○秒、○日、○年前を表示 let createdDate = "1686-01-01T12:00:00+0009" ContentView.formatter.locale = Locale(identifier: "ja_JP") let fmt = ISO8601DateFormatter() let date1 = fmt.date(from: createdDate)! let components = Calendar.current.dateComponents( [.day, .year, .month, .minute, .second], from: Date(), to: date1 ) let timeAgo = ContentView.formatter.localizedString(from: components) return VStack { VStack { Image(mapImage) .resizable() .aspectRatio(contentMode: .fit) .cornerRadius(12.0, antialiased: /*@START_MENU_TOKEN@*/true/*@END_MENU_TOKEN@*/) HStack { Spacer() Text(place).font(.caption).foregroundColor(.gray) .padding(.bottom, 5) } } Text(haiku).font(.title3).fontWeight(.bold) HStack { Image(systemName: "heart").font(.headline).foregroundColor(Color("pinkColor")) Text("225").font(.headline).foregroundColor(Color("pinkColor")) Spacer() }.padding(.top, 5) HStack { Image(userImage) .resizable() .frame(width: 30, height: 30) .clipShape(Circle()) HStack { Text(user).font(.headline).fontWeight(.light) + Text("・").font(.headline).fontWeight(.light) + Text(timeAgo).font(.headline).fontWeight(.light) } Spacer() HStack { Image(systemName: "text.bubble").font(.title).foregroundColor(.gray) Image(systemName: "heart.fill").font(.title).foregroundColor(Color("pinkColor")) } } }.padding() } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() .previewLayout(.fixed(width: 414, height: 391)) } }今後は今回作成したカードをリストにし、表示できるようにします。
以上です。
- 投稿日:2020-11-20T01:35:10+09:00
【SwiftUi】経過時間の表示とListViewのセルデザイン
はじめに
SwiftUIでRelativeDateTimeFormatterクラスを用いて、経過時間を取得できるようにすることと、取得した経過時間を表示することを目的とする。
UIのデザインはcakesのnote風のデザインを参考にカード型のViewを作ります。
今後は今回作成したカードに前回までに実装した地図と都道府県市町村名を表示できるようにし、Firebaseで更新できるようにすることが目的です。
前回までの記事は以下を参考ください。参考記事
【SwiftUI】Mapkitから取得した情報をFirebaseに保存する開発環境
OSX 10.15.7 (Catalina)
Xcode 12.2.0
CocoaPods 1.10.0RelativeDateTimeFormatterの実装
基準日時からの経過時間を出力するクラスです。Twitterなどの○秒前や○日前などを表示をすることができます。
ロケーションを設定することで英語表記や日本語表記に変更が可能になります。
以下では○秒前、○分前、○時間前、○日前、○年前をそれぞれ記載しています。参考記事
How to show a relative date and time using RelativeDateTimeFormatter
Relative date time formatting in SwiftUIimport SwiftUI let nowTime = Date() print(nowTime) let formatter = RelativeDateTimeFormatter() formatter.locale = Locale(identifier: "ja_JP") let fmt = ISO8601DateFormatter() // ○秒前 let createdDate = "2020-11-19T16:12:30+0000" print(createdDate) let date1 = fmt.date(from: createdDate)! let components = Calendar.current.dateComponents( [.day, .year, .month, .minute, .second], from: Date(), to: date1 ) let timeAgo1 = formatter.localizedString(from: components) print(timeAgo1) // ○分前 let createdDate2 = "2020-11-19T16:00:00+0000" print(createdDate2) let date2 = fmt.date(from: createdDate2)! let components2 = Calendar.current.dateComponents( [.day, .year, .month, .minute, .second], from: Date(), to: date2 ) let timeAgo2 = formatter.localizedString(from: components2) print(timeAgo2) // ○時間前 let createdDate3 = "2020-11-19T11:00:00+0000" print(createdDate3) let date3 = fmt.date(from: createdDate3)! let components3 = Calendar.current.dateComponents( [.day, .year, .month,.hour ,.minute, .second], from: Date(), to: date3 ) let timeAgo3 = formatter.localizedString(from: components3) print(timeAgo3) // ○日前 let createdDate4 = "2020-11-15T11:00:00+0000" print(createdDate4) let date4 = fmt.date(from: createdDate4)! let components4 = Calendar.current.dateComponents( [.year, .month, .day, .hour , .minute, .second], from: Date(), to: date4 ) let timeAgo4 = formatter.localizedString(from: components4) print(timeAgo4) // ○年前 let createdDate5 = "2000-11-15T11:00:00+0000" print(createdDate4) let date5 = fmt.date(from: createdDate5)! let components5 = Calendar.current.dateComponents( [.year, .month, .day, .hour , .minute, .second], from: Date(), to: date5 ) let timeAgo5 = formatter.localizedString(from: components5) print(timeAgo5)playgroundで出力した結果は以下のとおりです。
2020-11-19 16:12:35 +0000 2020-11-19T16:12:30+0000 5 秒前 2020-11-19T16:00:00+0000 12 分前 2020-11-19T11:00:00+0000 5 時間前 2020-11-15T11:00:00+0000 4 日前 2020-11-15T11:00:00+0000 20 年前
経過時間は自動で切り替えて表示されます。
RelativeDateTimeFormatterを実装し、経過時間を表示したカードを作る。
手順は以下のとおりです。
1. 地図、タイトル、作者、日時などを表示したカード型のViewをつくる
2. リストに先ほど作成したカードを表示LocationRow.swiftimport SwiftUI struct ContentView: View { var user = "松尾芭蕉" var userImage = "basho" var haiku = "古池や 蛙飛びこむ 水の音" var mapImage = "mapImage" var place = "東京都江東区" static let formatter = RelativeDateTimeFormatter() var body: some View { // ○秒、○日、○年前を表示 let createdDate = "1686-01-01T12:00:00+0009" ContentView.formatter.locale = Locale(identifier: "ja_JP") let fmt = ISO8601DateFormatter() let date1 = fmt.date(from: createdDate)! let components = Calendar.current.dateComponents( [.day, .year, .month, .minute, .second], from: Date(), to: date1 ) let timeAgo = ContentView.formatter.localizedString(from: components) return VStack { VStack { Image(mapImage) .resizable() .aspectRatio(contentMode: .fit) .cornerRadius(12.0, antialiased: /*@START_MENU_TOKEN@*/true/*@END_MENU_TOKEN@*/) HStack { Spacer() Text(place).font(.caption).foregroundColor(.gray) .padding(.bottom, 5) } } Text(haiku).font(.title3).fontWeight(.bold) HStack { Image(systemName: "heart").font(.headline).foregroundColor(Color("pinkColor")) Text("225").font(.headline).foregroundColor(Color("pinkColor")) Spacer() }.padding(.top, 5) HStack { Image(userImage) .resizable() .frame(width: 30, height: 30) .clipShape(Circle()) HStack { Text(user).font(.headline).fontWeight(.light) + Text("・").font(.headline).fontWeight(.light) + Text(timeAgo).font(.headline).fontWeight(.light) } Spacer() HStack { Image(systemName: "text.bubble").font(.title).foregroundColor(.gray) Image(systemName: "heart.fill").font(.title).foregroundColor(Color("pinkColor")) } } }.padding() } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() .previewLayout(.fixed(width: 414, height: 391)) } }今後は今回作成したカードをリストにし、表示できるようにします。
以上です。
- 投稿日:2020-11-20T00:03:56+09:00
Flutterチュートリアルを咀嚼する part1 -FlutterはWidgetまみれ-
Flutterって一つのソースを書くだけでiOSもAndroidもアプリ作ってくれるんだって
すごいなー
勉強してみよう対象のチュートリアル
https://codelabs.developers.google.com/codelabs/first-flutter-app-pt1#0
コピペしてできあがったもの
スタートアップ企業の名前をつけてあげるために単語二つの組み合わせをリスト化してくれるアプリ
ソースコード
main.dartimport 'package:flutter/material.dart'; import 'package:english_words/english_words.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Startup Name Generator', home: RandomWords(), ); } } class RandomWords extends StatefulWidget { @override _RandomWordsState createState() => _RandomWordsState(); } class _RandomWordsState extends State<RandomWords> { final _suggestions = <WordPair>[]; final _biggerFont = TextStyle(fontSize: 18.0); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Startup Name Generator'), ), body: _buildSuggestions(), ); } Widget _buildSuggestions() { return ListView.builder( padding: EdgeInsets.all(16.0), itemBuilder: /*1*/ (context, i) { if (i.isOdd) return Divider(); /*2*/ final index = i ~/ 2; /*3*/ if (index >= _suggestions.length) { _suggestions.addAll(generateWordPairs().take(10)); /*4*/ } return _buildRow(_suggestions[index]); }); } Widget _buildRow(WordPair pair) { return ListTile( title: Text( pair.asPascalCase, style: _biggerFont, ), ); } }順々にみていこう
import
import 'package:flutter/material.dart'; import 'package:english_words/english_words.dart';package:flutter/material.dart
これがないと始まらないっぽい
Flutterアプリの主役たちクラス
Widget
https://api.flutter.dev/flutter/widgets/Widget-class.html
Flutterフレームワークの中心的なクラス
FlutterではほとんどのものがWidget
Widget単位でアプリが構築されていくStatelessWidget
https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html
State(状態)を持たないWidget
不変(immutable)であり静的(static)
親のWidgetから引数を与えてあげることで描画される
反対はStatefulWidget※参考
https://tech-rise.net/difference-between-stateless-widget-and-stateful-widgetStatefulWidget
https://api.flutter.dev/flutter/widgets/StatefulWidget-class.html
チュートリアルの中で
Implementing a stateful widget requires at least two classes: 1) a StatefulWidget class that creates an instance of 2) a State class.
とあるように、statefulなWidgetを作るためには、②Stateクラスのインスタンスを生成する①StatefulWidgetクラスを用意する必要がある。
要はStateクラスとセットということらしい。State
https://api.flutter.dev/flutter/widgets/State-class.html
StatefulWidgetとセットになるもの。
StatefulWidgetの中でインスタンス化される。
StatefulWidgetのロジックはここで実装する。
Stateクラスの名前の頭には_(アンダーバー)をつける。BuildContext
https://api.flutter.dev/flutter/widgets/BuildContext-class.html
※参考
https://qiita.com/agajo/items/93d75aafe87bdc7b2026
https://itome.team/blog/2019/12/flutter-advent-calendar-day6/MaterialApp
https://api.flutter.dev/flutter/material/MaterialApp-class.html
マテリアルデザインアプリケーションに一般的に必要とされる多くのウィジェットをラップする便利なウィジェット。Scaffold
https://api.flutter.dev/flutter/material/Scaffold-class.html
AppBar
https://api.flutter.dev/flutter/material/AppBar-class.html
Text
https://api.flutter.dev/flutter/dart-html/Text-class.html
ListView
https://api.flutter.dev/flutter/widgets/ListView-class.html
EdgeInsets
https://api.flutter.dev/flutter/painting/EdgeInsets-class.html
Divider
https://api.flutter.dev/flutter/material/Divider-class.html
関数
runApp()
https://api.flutter.dev/flutter/widgets/runApp.html
指定されたウィジェットを膨らませて、画面に添付する。メソッド
build()
https://api.flutter.dev/flutter/dart-ui/ParagraphBuilder/build.html
Widgetの主なお仕事の一つ
Widgetをどんな内容で描画するかを決定するあたりが内包されているライブラリ
これを覚えていくことがはじめの一歩なんでしょうpackage:english_words/english_words.dart
チュートリアルの中で追加したライブラリ
よく使われる英単語を提供してくれるWordPair
generateWordPairs
main()
void main() => runApp(MyApp());実行部はここだけ
runApp()関数で引数のクラス(MyApp())を膨らませているmain()関数はdartのもの
https://dart.dev/guides/language/language-tour#the-main-function矢印(=>)構文だけど、これと同じ意味
void main() { runApp(MyApp()); }MyAppクラス
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Startup Name Generator', home: RandomWords(), ); } }main()に膨らまされるウィジェット
一番大元なのでStatelessWidgetを拡張したクラスである
build()メソッドを使ってMyAppの内容を描画するMaterialAppをreturnしている
MaterialAppではタイトルとホームの内容を設定している
ホームの中身であるRandomWords()は後述RandomWords()
class RandomWords extends StatefulWidget { @override _RandomWordsState createState() => _RandomWordsState(); } class _RandomWordsState extends State<RandomWords> { final _suggestions = <WordPair>[]; final _biggerFont = TextStyle(fontSize: 18.0); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Startup Name Generator'), ), body: _buildSuggestions(), ); } Widget _buildSuggestions() { return ListView.builder( padding: EdgeInsets.all(16.0), itemBuilder: /*1*/ (context, i) { if (i.isOdd) return Divider(); /*2*/ final index = i ~/ 2; /*3*/ if (index >= _suggestions.length) { _suggestions.addAll(generateWordPairs().take(10)); /*4*/ } return _buildRow(_suggestions[index]); }); } Widget _buildRow(WordPair pair) { return ListTile( title: Text( pair.asPascalCase, style: _biggerFont, ), ); } }大きく分けると
StatefulWidgetのRandomWords
そのStateクラスである_RandomWordsState
がある
チュートリアルが言うにはStatefulWidgetがWidgetそのもので
この中でロジックが記載されているStateクラスをインスタンス化することによってWidgetの内容をstatefulに変更しているとのこと
_RandomWordsStateにはランダムな単語の組み合わせを生成し、リスト形式で表示するためのロジックが記載されているFlutterではほとんど全てのものがWidgetとあるようにこのクラスにはたくさんのWidgetがある
Scaffold
AppBar
Text
ListView
ListTileそしてfunctionの戻り値も全てWidgetである
(全部についていて見落としてしまいそうだが頭についてるWidgetは戻り値の型である)
_buildSuggestions():複数行の単語ペアリストを生成する
_buildRow(WordPair pair):1行分の単語ペアリストを生成するスマホのウィジェットを組み合わせてホーム画面をお好みにしていくように
FlutterでもいろんなWidgetを組み合わせてアプリを作っていくようだ
- 投稿日:2020-11-20T00:03:56+09:00
Flutterチュートリアルを咀嚼する part1 (基本
Flutterって一つのソースを書くだけでiOSもAndroidもアプリ作ってくれるんだって
すごいなー
勉強してみよう対象のチュートリアル
https://codelabs.developers.google.com/codelabs/first-flutter-app-pt1#0
コピペしてできあがったもの
スタートアップ企業の名前をつけてあげるために単語二つの組み合わせをリスト化してくれるアプリ
ソースコード
main.dartimport 'package:flutter/material.dart'; import 'package:english_words/english_words.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Startup Name Generator', home: RandomWords(), ); } } class RandomWords extends StatefulWidget { @override _RandomWordsState createState() => _RandomWordsState(); } class _RandomWordsState extends State<RandomWords> { final _suggestions = <WordPair>[]; final _biggerFont = TextStyle(fontSize: 18.0); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Startup Name Generator'), ), body: _buildSuggestions(), ); } Widget _buildSuggestions() { return ListView.builder( padding: EdgeInsets.all(16.0), itemBuilder: /*1*/ (context, i) { if (i.isOdd) return Divider(); /*2*/ final index = i ~/ 2; /*3*/ if (index >= _suggestions.length) { _suggestions.addAll(generateWordPairs().take(10)); /*4*/ } return _buildRow(_suggestions[index]); }); } Widget _buildRow(WordPair pair) { return ListTile( title: Text( pair.asPascalCase, style: _biggerFont, ), ); } }順々にみていこう
import
import 'package:flutter/material.dart'; import 'package:english_words/english_words.dart';package:flutter/material.dart
これがないと始まらないっぽい
Flutterアプリの主役たちクラス
Widget
https://api.flutter.dev/flutter/widgets/Widget-class.html
Flutterフレームワークの中心的なクラス
FlutterではほとんどのものがWidget
Widget単位でアプリが構築されていくStatelessWidget
https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html
State(状態)を持たないWidget
不変(immutable)であり静的(static)
親のWidgetから引数を与えてあげることで描画される
反対はStatefulWidget※参考
https://tech-rise.net/difference-between-stateless-widget-and-stateful-widgetStatefulWidget
https://api.flutter.dev/flutter/widgets/StatefulWidget-class.html
チュートリアルの中で
Implementing a stateful widget requires at least two classes: 1) a StatefulWidget class that creates an instance of 2) a State class.
とあるように、statefulなWidgetを作るためには、②Stateクラスのインスタンスを生成する①StatefulWidgetクラスを用意する必要がある。
要はStateクラスとセットということらしい。State
https://api.flutter.dev/flutter/widgets/State-class.html
StatefulWidgetとセットになるもの。
StatefulWidgetの中でインスタンス化される。
StatefulWidgetのロジックはここで実装する。
Stateクラスの名前の頭には_(アンダーバー)をつける。BuildContext
https://api.flutter.dev/flutter/widgets/BuildContext-class.html
※参考
https://qiita.com/agajo/items/93d75aafe87bdc7b2026
https://itome.team/blog/2019/12/flutter-advent-calendar-day6/MaterialApp
https://api.flutter.dev/flutter/material/MaterialApp-class.html
マテリアルデザインアプリケーションに一般的に必要とされる多くのウィジェットをラップする便利なウィジェット。Scaffold
https://api.flutter.dev/flutter/material/Scaffold-class.html
AppBar
https://api.flutter.dev/flutter/material/AppBar-class.html
Text
https://api.flutter.dev/flutter/dart-html/Text-class.html
ListView
https://api.flutter.dev/flutter/widgets/ListView-class.html
EdgeInsets
https://api.flutter.dev/flutter/painting/EdgeInsets-class.html
Divider
https://api.flutter.dev/flutter/material/Divider-class.html
関数
runApp()
https://api.flutter.dev/flutter/widgets/runApp.html
指定されたウィジェットを膨らませて、画面に添付する。メソッド
build()
https://api.flutter.dev/flutter/dart-ui/ParagraphBuilder/build.html
Widgetの主なお仕事の一つ
Widgetをどんな内容で描画するかを決定するあたりが内包されているライブラリ
これを覚えていくことがはじめの一歩なんでしょうpackage:english_words/english_words.dart
チュートリアルの中で追加したライブラリ
よく使われる英単語を提供してくれるWordPair
generateWordPairs
main()
void main() => runApp(MyApp());実行部はここだけ
runApp()関数で引数のクラス(MyApp())を膨らませているmain()関数はdartのもの
https://dart.dev/guides/language/language-tour#the-main-function矢印(=>)構文だけど、これと同じ意味
void main() { runApp(MyApp()); }MyAppクラス
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Startup Name Generator', home: RandomWords(), ); } }main()に膨らまされるウィジェット
一番大元なのでStatelessWidgetを拡張したクラスである
build()メソッドを使ってMyAppの内容を描画するMaterialAppをreturnしている
MaterialAppではタイトルとホームの内容を設定している
ホームの中身であるRandomWords()は後述RandomWords()
class RandomWords extends StatefulWidget { @override _RandomWordsState createState() => _RandomWordsState(); } class _RandomWordsState extends State<RandomWords> { final _suggestions = <WordPair>[]; final _biggerFont = TextStyle(fontSize: 18.0); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Startup Name Generator'), ), body: _buildSuggestions(), ); } Widget _buildSuggestions() { return ListView.builder( padding: EdgeInsets.all(16.0), itemBuilder: /*1*/ (context, i) { if (i.isOdd) return Divider(); /*2*/ final index = i ~/ 2; /*3*/ if (index >= _suggestions.length) { _suggestions.addAll(generateWordPairs().take(10)); /*4*/ } return _buildRow(_suggestions[index]); }); } Widget _buildRow(WordPair pair) { return ListTile( title: Text( pair.asPascalCase, style: _biggerFont, ), ); } }大きく分けると
StatefulWidgetのRandomWords
そのStateクラスである_RandomWordsState
がある
チュートリアルが言うにはStatefulWidgetがWidgetそのもので
この中でロジックが記載されているStateクラスをインスタンス化することによってWidgetの内容をstatefulに変更しているとのこと
_RandomWordsStateにはランダムな単語の組み合わせを生成し、リスト形式で表示するためのロジックが記載されているFlutterではほとんど全てのものがWidgetとあるようにこのクラスにはたくさんのWidgetがある
Scaffold
AppBar
Text
ListView
ListTileそしてfunctionの戻り値も全てWidgetである
(全部についていて見落としてしまいそうだが頭についてるWidgetは戻り値の型である)
_buildSuggestions():複数行の単語ペアリストを生成する
_buildRow(WordPair pair):1行分の単語ペアリストを生成するスマホのウィジェットを組み合わせてホーム画面をお好みにしていくように
FlutterでもいろんなWidgetを組み合わせてアプリを作っていくようだ
- 投稿日:2020-11-20T00:03:56+09:00
Flutterチュートリアルを咀嚼する part1
Flutterって一つのソースを書くだけでiOSもAndroidもアプリ作ってくれるんだって
すごいなー
勉強してみよう対象のチュートリアル
https://codelabs.developers.google.com/codelabs/first-flutter-app-pt1#0
コピペしてできあがったもの
スタートアップ企業の名前をつけてあげるために単語二つの組み合わせをリスト化してくれるアプリ
ソースコード
main.dartimport 'package:flutter/material.dart'; import 'package:english_words/english_words.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Startup Name Generator', home: RandomWords(), ); } } class RandomWords extends StatefulWidget { @override _RandomWordsState createState() => _RandomWordsState(); } class _RandomWordsState extends State<RandomWords> { final _suggestions = <WordPair>[]; final _biggerFont = TextStyle(fontSize: 18.0); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Startup Name Generator'), ), body: _buildSuggestions(), ); } Widget _buildSuggestions() { return ListView.builder( padding: EdgeInsets.all(16.0), itemBuilder: /*1*/ (context, i) { if (i.isOdd) return Divider(); /*2*/ final index = i ~/ 2; /*3*/ if (index >= _suggestions.length) { _suggestions.addAll(generateWordPairs().take(10)); /*4*/ } return _buildRow(_suggestions[index]); }); } Widget _buildRow(WordPair pair) { return ListTile( title: Text( pair.asPascalCase, style: _biggerFont, ), ); } }順々にみていこう
import
import 'package:flutter/material.dart'; import 'package:english_words/english_words.dart';package:flutter/material.dart
これがないと始まらないっぽい
Flutterアプリの主役たちクラス
Widget
https://api.flutter.dev/flutter/widgets/Widget-class.html
Flutterフレームワークの中心的なクラス
FlutterではほとんどのものがWidget
Widget単位でアプリが構築されていくStatelessWidget
https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html
State(状態)を持たないWidget
不変(immutable)であり静的(static)
親のWidgetから引数を与えてあげることで描画される
反対はStatefulWidget※参考
https://tech-rise.net/difference-between-stateless-widget-and-stateful-widgetStatefulWidget
https://api.flutter.dev/flutter/widgets/StatefulWidget-class.html
チュートリアルの中で
Implementing a stateful widget requires at least two classes: 1) a StatefulWidget class that creates an instance of 2) a State class.
とあるように、statefulなWidgetを作るためには、②Stateクラスのインスタンスを生成する①StatefulWidgetクラスを用意する必要がある。
要はStateクラスとセットということらしい。State
https://api.flutter.dev/flutter/widgets/State-class.html
StatefulWidgetとセットになるもの。
StatefulWidgetの中でインスタンス化される。
StatefulWidgetのロジックはここで実装する。
Stateクラスの名前の頭には_(アンダーバー)をつける。BuildContext
https://api.flutter.dev/flutter/widgets/BuildContext-class.html
※参考
https://qiita.com/agajo/items/93d75aafe87bdc7b2026
https://itome.team/blog/2019/12/flutter-advent-calendar-day6/MaterialApp
https://api.flutter.dev/flutter/material/MaterialApp-class.html
マテリアルデザインアプリケーションに一般的に必要とされる多くのウィジェットをラップする便利なウィジェット。Scaffold
https://api.flutter.dev/flutter/material/Scaffold-class.html
AppBar
https://api.flutter.dev/flutter/material/AppBar-class.html
Text
https://api.flutter.dev/flutter/dart-html/Text-class.html
ListView
https://api.flutter.dev/flutter/widgets/ListView-class.html
EdgeInsets
https://api.flutter.dev/flutter/painting/EdgeInsets-class.html
Divider
https://api.flutter.dev/flutter/material/Divider-class.html
関数
runApp()
https://api.flutter.dev/flutter/widgets/runApp.html
指定されたウィジェットを膨らませて、画面に添付する。メソッド
build()
https://api.flutter.dev/flutter/dart-ui/ParagraphBuilder/build.html
Widgetの主なお仕事の一つ
Widgetをどんな内容で描画するかを決定するあたりが内包されているライブラリ
これを覚えていくことがはじめの一歩なんでしょうpackage:english_words/english_words.dart
チュートリアルの中で追加したライブラリ
よく使われる英単語を提供してくれるWordPair
generateWordPairs
main()
void main() => runApp(MyApp());実行部はここだけ
runApp()関数で引数のクラス(MyApp())を膨らませているmain()関数はdartのもの
https://dart.dev/guides/language/language-tour#the-main-function矢印(=>)構文だけど、これと同じ意味
void main() { runApp(MyApp()); }MyAppクラス
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Startup Name Generator', home: RandomWords(), ); } }main()に膨らまされるウィジェット
一番大元なのでStatelessWidgetを拡張したクラスである
build()メソッドを使ってMyAppの内容を描画するMaterialAppをreturnしている
MaterialAppではタイトルとホームの内容を設定している
ホームの中身であるRandomWords()は後述RandomWords()
class RandomWords extends StatefulWidget { @override _RandomWordsState createState() => _RandomWordsState(); } class _RandomWordsState extends State<RandomWords> { final _suggestions = <WordPair>[]; final _biggerFont = TextStyle(fontSize: 18.0); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Startup Name Generator'), ), body: _buildSuggestions(), ); } Widget _buildSuggestions() { return ListView.builder( padding: EdgeInsets.all(16.0), itemBuilder: /*1*/ (context, i) { if (i.isOdd) return Divider(); /*2*/ final index = i ~/ 2; /*3*/ if (index >= _suggestions.length) { _suggestions.addAll(generateWordPairs().take(10)); /*4*/ } return _buildRow(_suggestions[index]); }); } Widget _buildRow(WordPair pair) { return ListTile( title: Text( pair.asPascalCase, style: _biggerFont, ), ); } }大きく分けると
StatefulWidgetのRandomWords
そのStateクラスである_RandomWordsState
がある
チュートリアルが言うにはStatefulWidgetがWidgetそのもので
この中でロジックが記載されているStateクラスをインスタンス化することによってWidgetの内容をstatefulに変更しているとのこと
_RandomWordsStateにはランダムな単語の組み合わせを生成し、リスト形式で表示するためのロジックが記載されているFlutterではほとんど全てのものがWidgetとあるようにこのクラスにはたくさんのWidgetがある
Scaffold
AppBar
Text
ListView
ListTileそしてfunctionの戻り値も全てWidgetである
(全部についていて見落としてしまいそうだが頭についてるWidgetは戻り値の型である)
_buildSuggestions():複数行の単語ペアリストを生成する
_buildRow(WordPair pair):1行分の単語ペアリストを生成するスマホのウィジェットを組み合わせてホーム画面をお好みにしていくように
FlutterでもいろんなWidgetを組み合わせてアプリを作っていくようだ