- 投稿日:2020-01-17T22:38:42+09:00
"The bundle uses a bundle name or display name that is already taken."が出た時の対処法
- 投稿日:2020-01-17T21:02:35+09:00
スマホアプリ開発者のための2019年動向まとめ
はじめに
2019年は新元号「令和」のスタートやラグビーワールドカップなどなんとなくめでたい年でした。年始まで忙しかったので2020年の1月中旬ですが2019年のスマホアプリ業界をこっそりまとめます。
個人的には2019年はAndroidアプリを中心にネイティブアプリ開発保守をしていました。
スマホアプリ開発に携わっていない人もこの記事を見れば2019年のいろいろが分かるかも。
振り返り用に「ふむふむ」「へー」程度に見ていただければ幸いです。【前年】
スマホアプリ開発者のための2018年動向まとめ
Unityでスマホアプリ(特にプラグイン)を開発している人のための2017年対応まとめ
Unityでスマホアプリ(特にプラグイン)を開発している人のための2016年対応まとめ通信回線について
約10年に1度の通信回線アップデート、5Gがついにはじまりました。
2019年4月に米Verizonが開始し、9月に米Qualcommが開催した「2019 Future of 5G」では半年以内に30以上の通信事業者が5Gを開始または開始予定としていることが発表されました。https://www.verizon.com/about/our-company/5g
https://www.qualcomm.com/documents/2019-future-5g-presentation日本ではdocomo、KDDIが2019年9月にプレサービスを開始し、2020年を目処に商用サービス開始予定です。高速、大容量、低遅延、多接続、低消費電力などがキーワードとしてあげられています。
https://www.nttdocomo.co.jp/corporate/technology/rd/tech/5g/
https://www.softbank.jp/biz/5g/
https://biz.kddi.com/5g/また、3Gの停波のお知らせを公開し、auは2022年、SoftBankは2024年、docomoは2026年に停波となることが決定されました。これによってガラケーやらくらくホンを使用していたシニア層がスマホに大量流入することが予想されます。
https://www.nttdocomo.co.jp/info/news_release/2019/10/29_00.html
https://news.kddi.com/kddi/corporate/newsrelease/2018/11/16/3428.html
https://www.softbank.jp/mobile/network/3g-end/端末について
Appleからは例年通り9月にiPhone 11, iPhone 11 Pro, iPhone 11 Pro Maxが発売、Googleからは5月にPixel3a, 10月にPixel4が発売されました。
iPhoneもPixelも基本的にはカメラ機能推しで「夜景モード」という言葉は今年浸透した印象です。2019年は数少ないですがGalaxyやLGから折りたたみ端末(Foldable端末)が発売されました。Microsoftからは「Surface Duo」というAndroid端末が発表され2020年のホリデーシーズンに発売予定です。
5G対応の端末が2019年から発売され2019年12月現在は約30機種に増えました。2020年は対応機種が増え日本からも発売されることが予定されています。
2019年のスマホサービスについて
決済サービスの増加
個人的に大きいと思ったスマホアプリのニュースは2019年2月のPaypay100億円キャンペーンでした。
各店のPOSも多くの決済方法に対応し、生活が一変しました。
非接触方式に比べるとアプリ立ち上げやバーコード提示など不便な印象でしたが、
増税時のキャッシュバックキャンペーンなども後押しし、バーコード/QRコード決済が増えました。
Paypay、LINE Pay、メルペイ、Origami Pay、Kyash、ファミペイ、Origami Pay、楽天ペイ、セブンペイなどいろんなペイの選択肢が増えました(そして消えたサービスもありました)スマホゲームについて
2019年は日本の大手企業のリリースが多い年でした。
任天堂からはマリオカートツアー、ドクターマリオワールド、ポケモンマスターズと2019年で3本のリリースがありました。
また、ドラゴンクエストウォークなどの位置ゲームに関して世界的にリリースが多く、Googleからゲーム事例の記事が投稿されています。魅力あるゲーム体験を実現するGoogle Maps Platformの新機能と最新ゲーム事例
https://developers-jp.googleblog.com/2019/12/new-features-contextualized-gameplay-and-new-games-built-google-maps.htmlまた、ゲームのサービス形態が変化した年でした。Appleからは定額制サービスのApple Arcade、GoogleからはクラウドゲームのStadiaが発表されサービス開始しました。
子供向けプライバシーの保護の強化
スマホに限らずですが、YouTubeで子供向けプライバシー保護の取り扱いが大きく変更されました。
子供向けであると判断された、あるいはそう申告されたすべてのコンテンツについて、視聴者は無条件で子供と見なされるようになりました。https://youtube.googleblog.com/2019/09/an-update-on-kids.html
https://youtube.googleblog.com/2020/01/better-protecting-kids-privacy-on-YouTube.html子供向けプライバシー保護の強化はYouTubeのみでなくGoogle Play Serviceにも実施され、
自分が公開している子供向けアプリもGoogle Play Serviceを実装しているという理由で2019年に突然リジェクトされました。(参考: 2019年以降、GooglePlayの子供向けゲームアプリに○○を実装してはいけない)iOSも例外ではなく9月に「子ども向け」カテゴリガイドラインが更新されました。
2020年3月3日までは対応の猶予期間となっています。すべての新規Appはこのガイドラインに従う必要があります。また、できるだけ早く既存のAppを更新することをお勧めします。既存のAppにこのガイドラインを適合するのにさらに時間が必要な場合を考慮し、コンプライアンスに準拠させるために2020年3月3日までさらに6か月の猶予期間を設けることにしました。
iOS
iOS13
iOS 13をプレビュー
https://www.apple.com/jp/newsroom/2019/06/apple-previews-ios-13/
iOS 13 Release Notes
https://developer.apple.com/documentation/ios_ipados_release_notes/ios_13_release_notes2019年9月19日にiOS13の提供が開始されました。
SwiftUI、ダークモード、SF SymbolsなどUI周りが大きく変更されました。
ただしSwiftUIで開発したアプリはiOS13以降のみの対応となるため、完全移行は数年かかりそうです。
iPad向けのOSがiOSからiPadOSになり、iPad用AppをmacOSへ用意に移植できるProject CatalystもWWDC19で発表されました。Submit Your iOS Apps to the App Store
https://developer.apple.com/news/?id=09102019a&1568158483
Modernizing Your UI for iOS 13
https://developer.apple.com/videos/play/wwdc2019/224/iOSアップデートにより、要件も更新されました。
2020年4月からiOS13および3rd-genのiPad Pro対応必須となり、同時に以下を要件としています。
- LaunchScreenのStoryboard化
- 複数サイズのサポート
- 分割スクリーンのマルチタスク化
参考:
iOSのその他対応
その他にもPUSH通知、UIWebView受付終了の告知がされています。
Apple Push Notification service(APNs)は、2020年11月以降レガシーバイナリプロトコルをサポートしなくなります。
App Storeは、2020年4月からUIWebViewを使った新しいAppの受付を終了し、2020年12月からUIWebViewを使ったAppのアップデートの受付を終了します。
Android
Android10
ようこそ!Android10
https://developers-jp.googleblog.com/2019/09/android-10.html2019年9月3日にAndroid10の提供が開始されました。
ジェスチャーナビゲーション対応、5G対応、折りたたみ画面対応、セキュリティ強化などが含まれています。詳細なこちらへ > Android 10対応したので個人的まとめ (RSSリーダーアプリ編)
APIレベル28(Android 9)以上が必須に
2018年までの必須APIレベルは26でしたが今年は28になりました。
APIレベル28の変更点として、デフォルトのネットワークセキュリティ構成がhttps通信のみ許可になりました。
http通信を行うにはドメインをホワイトリストに追加するなどの対応が必要になります。2019年のターゲットAPIレベル要件の拡大について
https://developers-jp.googleblog.com/2019/03/2019-api.htmlAndroidでのTLS採用に関する最新情報
https://developers-jp.googleblog.com/2020/01/android-tls.htmlまた、2019年8月以降64ビットが必須要件になりました。
Unity5.6以前を使用したゲームの場合は2021年8月までの延長期間が与えられています。アプリを64ビット要件に対応させましょう
https://developers-jp.googleblog.com/2019/02/get-your-apps-ready-for-64-bit.html2年連続でAPIレベルが夏から秋にかけてAPIレベルの底上げを行っています。
例年通りだと2020年も行われることが予想されます。
旧サポートライブラリの最終バージョンが28なので、
APIレベル29対応では必然的にAndroidX対応が必要となります。
余裕があるときにAndroidX対応をしていたほうが良さそうです。Android関連のドキュメントの拡充
2019年1月にAndroidのCodelabが公開されました。
基礎コースと応用コースが用意され、学習が容易になりました。https://developer.android.com/courses
AndroidXはドキュメントページで最新バージョンがわかるようになった他、
Feedでのバージョン情報提供もはじまりました。
SlackなどでFeedを登録しておけば最新ライブラリの情報がキャッチ可能になります。https://developer.android.com/jetpack/androidx/versions
https://developer.android.com/feeds/android-release-notes.xmlAndroidのその他
2018年末のKotlin1.3でコルーチンが正式対応となり、Google Developers Blogでもコルーチン関連の記事が公開されました。
プロジェクトの動的モジュール化やコード圧縮ツールR8も注目のトピックとしてあげられています。
- Android でコルーチン(パート I): 背景を理解する
- 動的機能モジュールからコードにアクセスするパターン
- Google の新しいコード短縮ツール R8 が Android studio 3.3 beta にて利用可能です
また、Project Marbleという以前からのAndroid Studio改善の取り組みが反映された、Android Studio 3.5がリリースされました。
詳細はこちら >Android Studio3.5の変更点をもっと詳しく知りたい..!2020年春に登場するKotlin1.4
Kotlin 1.4の計画および将来的な展望
https://blog.jetbrains.com/jp/2020/01/16/273112月に行われたKotlinConf 2019でKotlin1.4の展望が発表されました。
(ちょうど昨日に日本語版blogが更新されました!)
マルチプラットフォーム化やKotlinのSAM変換についての変更などがあります。Flutter
2019年はFlutter関連のニュースも多くありました。
6月にFlutter for Web発表、12月にはFlutter単独で技術イベントFlutter Interactが行われ注目度は今年も上がっています。Flutter Interact
https://developers.google.com/events/flutter-interactFlutterの追い風(?)でDartもバージョンアップが頻繁に行われ、
2018年末の最新バージョンは2.0でしたが2019年末はDart2.7になり、
コレクション機能や拡張メソッド対応など一年で様変わりしました。
DartPadというDartを気軽に試すことができるツールも登場しました。DartPad
https://dartpad.dev/Flutterはコンテストも多く開催し、
5月には5KBで作るFlutter Create、11月には時計を作るFlutter Clockを発表しました。
# Flutter Clockの参加締切は2020年1月20日までなのでまだ間に合います。React NativeやFlutterのUI構築手法
React NativeやFlutterのUI構築手法はネイティブ開発に影響を与え
2019年に「Jetpack Compose」「SwiftUI」が続けて発表されています。
UIはコードベースでプレビューを確認しながら作るという手法が近くに一般化しそうです。Unity
スマホ関係者はUnite 2019の基礎公演、開発者は開発ロードマップ最新情報のYouTube動画を見るのがおすすめです。
基礎公演40:00ではVR/ARや自動運転、アニメーション活用に関して、
非ゲーム分野でシミュレーターとしてのUnity活用概要があります。Unite 2019 基礎公演
https://youtu.be/zLQ9oY08p84?t=2405Unity開発ロードマップ最新情報では直近のUnity更新内容が紹介されています。
Unity開発ロードマップ最新情報
https://www.youtube.com/watch?v=o9EJu4LRIdYDOTS (Data-Oriented Technology Stack)
DOTS - Unity の新しいマルチスレッド対応の Data-Oriented Technology Stack
https://unity.com/ja/dotsUnityはUnityを根幹から変える取り組みが行われており、DOTSに置き換わります。
- Entity 1.0 (2020.1〜)
- DOTS NetCode (2020.1〜)
- DOTS Audio
- DOTS Physics
- DOTS Animation
エディタUIも再設計されビジュルスクリプティング機能もベータ公開予定。
映像向けパイプラインにはPythonサポートされます。
その他として、Serializeが進化してリファレンスがSerialize可能になりましたうれしい。モバイル向けの変更
モバイル向けに以下がロードマップの動画内で発表されています。
Unity as a LibraryはUnityとネイティブアプリの関係性を大きく変化させそうです。
- Project Tiny: Instant Runのような仕組みを提供。
- Unity Distribution Portal: Apple, Google以外のプラットフォームにも複数ゲーム配信ハブシステムも提供。
- Unity as a Library: ネイティブアプリ向けにUnityで作ったアプリをライブラリとして使用できる機能。
まとめ
2019年はだいたい以下のような感じでした(個人の感想です)
- 2019年のスマホは決済サービスが流行(増税の影響?)
- 2019年のスマホゲームは最大手参入と新サービス形態(Apple Arcade, Stadio)。
- 2019年は子供向けプライバシー強化が大きく行われた
- 2020年はとにかく5Gを中心に変化
- ネイティブのUI開発は旧手法・新手法(SwiftUI, Jetpack Compose)・別手法(Flutter, React Native)から選択する必要あり。
- Unityは新手法のDOTSに改装中
告知
2月のDroidKaigi 2020でビジュアルリグレッションテストについて話します。まだ資料できてません。
https://droidkaigi.jp/2020/accepted/この記事が参考になったら「いいね」を、あとで読む場合は「ストック」を、投げ銭したくなったらPaypayで以下をおねがいします。
今年もよろしくおねがいいたします。
- 投稿日:2020-01-17T19:48:30+09:00
NeumorphismをSwiftUIで簡単に実装できるライブラリ、Neumorphismicを作ってみた
先日Neumorphism: 令和時代のスキューモーフィズムを読みました。
これが流行る頃にはSwiftUIも使えるようになってるだろう…ということでSwiftUIでNeumorphismのライブラリを作ってみました。
SwiftPMにしか対応していませんが、Xcode 11からとても使いやすくなりましたし、SwiftUIのOSSなのでこれで十分だと思います。スターつけてくださると嬉しいです!
完成形
Demoの画面です。SwiftUIということで全プラットフォームのDemoを一応作りましたが、iOS以外は図形が表示されるだけの手抜きです。
使い方
簡単な使い方はこんな感じです。2層目以降は
ZStack
で背景色をつける必要もないですし、.environment
も必要ありません。下のコードだと少し複雑に見えるかもしれませんが、各Viewで増えるのは.modifier(NMConvexModifier())
のみです。下のコードもSwiftUIを少し触った方ならすぐわかると思います。struct ContentView: View { let baseColor = Color(hex: "C1D2EB") var body: some View { ZStack { baseColor .edgesIgnoringSafeArea(.all) Circle() .fill(baseColor) .frame(width: 300, height: 200) .modifier(NMConvexModifier()) .environment(\.nmBaseColor, baseColor) } } }作り方
実際のコードとは多少違います。
ModifierでShadowを実装する
Modifierについてはこの記事でひと通りわかると思います。簡単にいうと
.font
とか.frame
とかをまとめてView
に適合できるやつです。
SwiftUIでもshodowは1つしか追加できません。なのでZStack
でView
を2つ重ねてそれぞれに.shadow
をつける必要があります。struct ConvexModifier: ViewModifier { let lightShadowColor: Color let darkShadowColor: Color func body(content: Content) -> some View { ZStack { content .shadow(color: darkShadowColor, radius: 16, x: 9, y: 9) content .shadow(color: lightShadowColor, radius: 16, x: -9, y: -9) } } }しかし、これだけでは影の色をいちいち入力する必要があります。
色をEnvironmentで伝搬する
SwiftUIでは
@Environment
を使うことでその子View
全てに値を伝えることができます。詳しくはこの記事を読んでください。
そしてこれは自作することもできます。Neumorphismでは基本的にView
に1色しか使わないためこれが非常に有効です。さらに、ConvexModifier
もbaseColor
を基準に影の色を決めればよくなります。自作する方法はこちらをご覧ください。struct BaseColorKey: EnvironmentKey { static let defaultValue: Color = .gray } extension EnvironmentValues { var baseColor: Color { get { self[BaseColorKey.self] } set { self[BaseColorKey.self] = newValue } } }さて、色を変換したいわけだけど…
パッと見、SwiftUIの
Color
からはrgbやhueや取得できそうにありません。しかし#C1D2EBFF
のようにカラーコードを返してくれる.description
があります。ということでカラーコードからColorを生成(このリンクではUIColor)できるようにし、RGBとHSL、RGBとHSBの変換コードを用意します。
Color
から色情報を取れるとわかったので、早速lighterColor
を実装します。func getRGBA() -> (r: Double, g: Double, b: Double, a: Double) { let string = String(self.description.dropFirst()) let v = Int(string, radix: 16) ?? 0 let r = Double(v / Int(powf(256, 3)) % 256) / 255 let g = Double(v / Int(powf(256, 2)) % 256) / 255 let b = Double(v / Int(powf(256, 1)) % 256) / 255 let a = Double(v / Int(powf(256, 0)) % 256) / 255 return (r, g, b, a) } func getHSLA() -> (h: Double, s: Double, l: Double, a: Double) { let (r, g, b, a) = getRGBA() let (h, s, l) = ColorTransformer.rgbToHsl(r: r, g: g, b: b) return (h, s, l, a) } func lighter(_ value: Double) -> Color { let (h, s, l, a) = getHSLA() return Color(hue: h, saturation: s, lightness: min(l + value, 1), opacity: a) } func darker(_ value: Double) -> Color { let (h, s, l, a) = getHSLA() return Color(hue: hsb.h, saturation: hsb.s, lightness: max(l - value, 0), opacity: a) }struct ColorExtension_Previews: PreviewProvider { static var previews: some View { let color = Color(hex: "C1D2EB") return Group { ColorPreview(color) ColorPreview(color.lighter(0.12)) ColorPreview(color.darker(0.18)) } .previewLayout(.fixed(width: 200, height: 100)) } }ConvexModifierを完成させる
材料は揃ったので合わせてみましょう。
struct ConvexModifier: ViewModifier { @Environment(\.baseColor) var baseColor: Color func body(content: Content) -> some View { ZStack { content .shadow(color: baseColor.darker(0.18), radius: 16, x: 9, y: 9) content .shadow(color: baseColor.lighter(0.12), radius: 16, x: -9, y: -9) } } }struct ConvexModifier_Previews: PreviewProvider { static var previews: some View { ZStack { Color(hex: "C1D2EB") .edgesIgnoringSafeArea(.all) Circle() .fill(Color(hex: "C1D2EB")) .modifier(ConvexModifier()) .frame(width: 300, height: 300) } .environment(\.baseColor, Color(hex: "C1D2EB")) } }
.environment
でbaseColor
を伝えるの忘れないようにしましょう。
いい感じですね!
environment
を使ったので当然struct ConvexModifier_Previews: PreviewProvider { static var previews: some View { ZStack { Color(hex: "C1D2EB") .edgesIgnoringSafeArea(.all) Circle() .fill(Color(hex: "C1D2EB")) .frame(width: 300, height: 300) .modifier(ConvexModifier()) // `environment`で影の色を変える .environment(\.baseColor, Color.red) } .environment(\.baseColor, Color(hex: "C1D2EB")) } }とできるだろうと思っていたのですができませんでした。
.red
の時は黒い影が出てきて、その他の場合は影がなくなりました。Color(hex:)
を使ったら行けたのでよくわかりません。Highlight時に表示を変えられるButtonも作ってみた
ハイライト時にNeumorphismではどうするのが正解なんだろうと考えるためにとりあえず作ってみました。個人的に標準
Button
は ハイライト時に色が薄すぎる気がするのでこれを使ってますが、標準のButton
でもいい気がします。押下時にボタンを小さくしたいときなどに使ってみてください。struct HighlightableButton<Label>: View where Label: View { private let action: () -> Void private let label: (Bool) -> Label public init( action: @escaping () -> Void, label: @escaping (Bool) -> Label ) { self.action = action self.label = label } @State private var isHighlighted = false public var body: some View { label(isHighlighted) .animation(.easeOut(duration: 0.05)) .gesture(DragGesture(minimumDistance: 0) .onChanged { _ in withAnimation { self.isHighlighted = true } } .onEnded { _ in self.action() withAnimation { self.isHighlighted = false } } ) } }struct ConvexModifier_HighlightableButton_ForPreviews: View { @State var isSelected = false var body: some View { HighlightableButton(action: { self.isSelected.toggle() }) { isH in Image(systemName: self.isSelected ? "house.fill" : "house") .resizable() .aspectRatio(contentMode: .fit) .frame(width: isH ? 54 : 60) .foregroundColor(Color(hex: "C1D2EB").darker(value: 0.18)) .background( Circle() .fill(Color(hex: "C1D2EB")) .frame(width: isH ? 90 : 100, height: isH ? 90 : 100) .modifier(ConvexModifier()) ) .opacity(isH ? 0.6 : 1) } } }
.modifier(ConvexModifier())
はButton
の中に書いてください(標準のButton
でも同じです)。外に書くときちんと適用されません。ForPreviews
みたいな名前になっているのは、PreviewProvider
の中には@State
が置けないからです。
FloatingTabViewも作ってみた
@touyouさんもタブを作ってることだし作るかーみたいな感じで作ってみました。
ViewBuilder
を読み解こうとまでは思わなかったので(そもそもできるんですかね)、標準のTabView
のような綺麗さはありませんが、まあ使えるのではないでしょうか。タブの数は4つまでにしてみました。標準のTabView
にあるその他を実装する気力はなかったので切り捨てています。
使い方はこんな感じです。struct FloatingTabView_ForPreviews: View { enum Season: String, CaseIterable { case spring, summer, fall, winter var color: Color { switch self { case .spring: return .pink case .summer: return .blue case .fall: return .orange case .winter: return .white } } } @State var season: Season = .spring var body: some View { FloatingTabView(selection: $season, labelText: { s in s.rawValue }, labelImage: { _ in Image(systemName: "camera") }) { s in s.color.edgesIgnoringSafeArea(.all) } } }例を作るのが面倒なのが目に見えますね…。
labelImage
なんてカメラだけですし。この例では色を変えていますが、Neumorphismでは色を変えるのはご法度なので注意。(もちろん局所的にアクセントとして使うのはOKです)
ああ、影の色が汚い…。まあ色変えるとこうなるよっていう悪い例と思ってください。
ちなみにGeometryReader
のせいかLive PreviewにしていないとTabが下に落ちてしまいました。SwiftUIは7不思議どころじゃありません。そこら辺に穴が一杯です。全く理由がわからず何となくLive Previewにしてみたところ合っていたことがわかりました。恐ろしや。凹も作りたかったけど
凹凸どちらも作りたかったのですが、凹の方はいい案が思い浮かばず、凸だけになってしまいました。適合したい
aView
よりひとまわり大きいbView
を作って、そこからaView
の大きさを切り抜いて、aView
の上にbView
を2つ置いて影をつければ行けそうだなとは思ったんですが、くり抜く方法がわかりませんでした。Path
を使えば何とかなりそうですが、View
の形を取る方法もないですし…。使う上での諸注意
HighlightableButton
のところでも書きましたが、Button
で使う際は.modifier(ConvexModifier())
をButton
の中に書いてください。そうしないときれいに作れません。
またBinding
系のコンポーネントは2つ同時にViewに存在すると使えなくなるようです。TextField("C1D2EB", text: $model.userInput) .foregroundColor(baseColor.darker(0.5)) .padding(5) .background( RoundedRectangle(cornerRadius: 5, style: .continuous) .fill(baseColor) .modifier(NMConvexModifier(radius: 9)) )のように
background
に設定したView
に.modifier(ConvexModifier())
してください。View
の量的にもこちらの方がパフォーマンスもいいです。NeumorphismではViewの量が多くなりがちなので。初OSS & 初Qiita?
cocoapodsなどにも対応したかったのですが、SwiftUIのOSSですし、自分の学ぶ量としてもSwiftPMだけで十分だろうとSPMのみになっています。それでも十分つまづきまくりましたし。
初めてのOSSなので、改善点などたくさんあると思います。もしなんかあったらTwitterなどに送ってくださると嬉しいです!(もちろんissueでも)Qiitaも初投稿ですが、そろそろ開発から離れて受験勉強しないと浪人する未来しか見えないので当分記事を書くことはないでしょう。1年後に戻って来れるように頑張ります。
いいねとスターつけてくださると嬉しいです!
Neumorphismic - GitHub
- 投稿日:2020-01-17T14:38:32+09:00
iOS の Dynamic Type でテキストサイズはどのくらい変化するのか?
はじめに
iOS のアクセシビリティ機能の1つにユーザーインターフェース上のテキストサイズを自動的にスケーリングする Dynamic Type があります。
Scaling Fonts Automatically - UIKit | Apple Developer
Android ではテキストに対して Scale-independent Pixels (sp) という単位でのサイズ指定するのとは異なり、テキストに対して Header, Body のような用途別のスタイルで指定するのが特色です。
そのため、ユーザーのサイズ設定に応じて各スタイルのフォントサイズがどのように変化するのかが想像しにくいため、サンプルアプリを作って見た目と数値で確認できるようにしてみました。
サンプルアプリ
サンプルアプリのリポジトリはこちらです。
temoki/UIKit_DynamicType - GitHub
アプリを起動すると、デバイスの現在の設定に応じてカテゴリ別にテキストとそのサイズが表示されます。
フォントサイズを決める変数
UIContentSizeCategory
UIContentSizeCategory - UIKit | Apple Developer Documentation
ユーザーが iOS のアクセシビリティ設定で変更可能なテキストサイズのカテゴリです。「さらに大きな文字」を ON にすると、最大 12 段階でサイズを変更できることになります。
name case rawValue XS .extraSmall
"UICTContentSizeCategoryXS"
S .small
"UICTContentSizeCategoryS"
M .medium
"UICTContentSizeCategoryM"
L .large
"UICTContentSizeCategoryL"
XL .extraLarge
"UICTContentSizeCategoryXL"
XXL .extraExtraLarge
"UICTContentSizeCategoryXXL"
XXXL .extraExtraExtraLarge
"UICTContentSizeCategoryXXXL"
A11yM .accessibilityMedium
"UICTContentSizeCategoryAccessibilityM"
A11yL .accessibilityLarge
"UICTContentSizeCategoryAccessibilityL"
A11yXL .accessibilityExtraLarge
"UICTContentSizeCategoryAccessibilityXL"
A11yXXL .accessibilityExtraExtraLarge
"UICTContentSizeCategoryAccessibilityXXL"
A11yXXXL .accessibilityExtraExtraExtraLarge
"UICTContentSizeCategoryAccessibilityXXXL"
UIFont.TextStyle
UIFont.TextStyle - UIFont | Apple Developer Documentation
UIKit の各種コントロールに設定するテキストスタイルです。
name case rawValue Large Title .largeTitle
"UICTFontTextStyleTitle0"
Title 1 .title1
"UICTFontTextStyleTitle1"
Title 2 .title2
"UICTFontTextStyleTitle2"
Title 3 .title3
"UICTFontTextStyleTitle3"
Headline .headline
"UICTFontTextStyleHeadline"
Subhead .subheadline
"UICTFontTextStyleSubhead"
Body .body
"UICTFontTextStyleBody"
Callout .callout
"UICTFontTextStyleCallout"
Footnote .footnote
"UICTFontTextStyleFootnote"
Caption1 .caption1
"UICTFontTextStyleCaption1"
Caption2 .caption2
"UICTFontTextStyleCaption2"
テキストサイズの変化
UIContentSizeCategory と UIKit.TextStyle の組み合わせによるフォントサイズを表にまとめてみました。
XS S M L XL XXL XXXL A11yM A11yL A11yXL A11yXXL A11yXXXL Large Title 31 32 33 34 36 38 40 44 48 52 56 60 Title 1 25 26 27 28 30 32 34 38 43 48 53 58 Title 2 19 20 21 22 24 26 28 34 39 44 50 56 Title 3 17 18 19 20 22 24 26 31 37 43 49 55 Headline 14 15 16 17 19 21 23 28 33 40 47 53 Subhead 12 13 14 15 17 19 21 25 30 36 42 49 Body 14 15 16 17 19 21 23 28 33 40 47 53 Callout 13 14 15 16 18 20 22 26 32 38 44 51 Footnote 12 12 12 13 15 17 19 23 27 33 38 44 Caption1 11 11 11 12 14 16 18 22 26 32 37 43 Caption2 11 11 11 11 13 15 17 20 24 29 34 41 グラフにもしてみました。
「さらに大きな文字」が ON の場合に想像以上に大きなフォントサイズになることがわかりますね。この状態でもレイアウトが破綻しないアプリを作るのはなかなか大変そうです?
MAXまで大きくしたら設定アプリはこうなる pic.twitter.com/Qn3sFIpGEn
— Tomoki Kobayashi??? (@temoki) January 7, 2020
この記事では Xcode 11.3 と iOS 13.3 シミュレータで確認した結果を掲載しています。
- 投稿日:2020-01-17T05:15:02+09:00
(swift)画像のデータサイズを縮小する方法(UIImage)
方法
UIGraphicsImageRenderer
を使用することで、画像のデータサイズを変更することができます。以下の
Extension
を使用することで、resizedメソッド
が使えます。
(参考: https://stackoverflow.com/questions/29137488/how-do-i-resize-the-uiimage-to-reduce-upload-image-size)extensionextension UIImage { //データサイズを変更する func resized(withPercentage percentage: CGFloat) -> UIImage? { let canvas = CGSize(width: size.width * percentage, height: size.height * percentage) return UIGraphicsImageRenderer(size: canvas, format: imageRendererFormat).image { _ in draw(in: CGRect(origin: .zero, size: canvas)) } } }使用例var usersImage = UIImage() //ここでは、UIImagePickerControllerを使用しています。 let pickerImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage //pickerで取得したUIImageのサイズを90%カットする。 let resizedImage = pickerImage?.resized(withPercentage: 0.1) //usersImageに代入する usersImage = resizedImage
UIGraphicsImageRenderer
とは?A graphics renderer for creating Core Graphics-backed images.
(和訳:Core Graphics
-backed画像を作成するためのグラフィックスレンダラー。)
(引用: https://developer.apple.com/documentation/uikit/uigraphicsimagerenderer)
Core Graphics
とは?
Quartz
テクノロジーのパワーを活用して、高忠実度の出力で軽量の2Dレンダリングを実行します。パスベースの描画、アンチエイリアスレンダリング、グラデーション、画像、カラーマネジメント、PDFドキュメントなどを処理します。
(引用: https://developer.apple.com/documentation/coregraphics)
Quartz
とは?ユーザーがスライドショーとCore Imageフィルターを使用して、画像を閲覧、編集、保存できるようにします。
(引用: https://developer.apple.com/documentation/quartz)つまり?
UIGraphicsImageRenderer
は、Core GraphicsフレームワークとQuartzフレームワークを使用して、画像(UIImage)の作成や編集を実行します。引用文献(スペシャルサンクス)