UIDocumentPickerViewControllerの'init(documentTypes:in:)' was deprecated in iOS 14.0 解決策

元々: let documentPicker = UIDocumentPickerViewController(documentTypes: ["public.json"], in: .import) 現在: let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: [.json])

'requestReview()' was deprecated in iOS 14.0 解決策

SKStoreReviewController.requestReview()を下記コードに変更する: if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene { SKStoreReviewController.requestReview(in: scene) } 関連文章: cecil-it.hatenadiary.com

Kotlin Unwrap an Optional Variable

val name: String? = "Cecil" name?.let { println(it) } ?: run { println("name is null") }

StoryBoardでSwiftUIをプレビューする

import SwiftUI import PlaygroundSupport struct ContentView: View { var body: some View { Text("Hello World") } } PlaygroundPage.current.liveView = UIHostingController(rootView: ContentView())

Programmatic Navigation Link

struct ViewA: View { @State private var isShowingViewB = false var body: some View { VStack { Button("Show View B") { isShowingViewB = true } NavigationLink( isActive: $isShowingViewB, destination: { ViewB() }, label: { EmptyView() } ) } }…

Dictionaryのキー存在しない時デフォルトバリューを提供する

let dic = ["dog": 1, "cat": 2] print(dic["chicken", default: 0]) // outputは0

SwiftのDataをKotlinのByteArrayに変換

KMM

extension Data { func toKotlinByteArray() -> KotlinByteArray { let byteArray = [UInt8](self) let kotlinByteArray = KotlinByteArray(size: Int32(byteArray.count)) for (i, byte) in byteArray.enumerated() { kotlinByteArray.set(index: Int32(i),…

Indices

let array = ["A", "B", "C"] for i in array.indices { print(i, array[i]) } equals let array = ["A", "B", "C"] for i in 0..

フォント追加

ステップ1 ステップ2 現在使えるフォントを確認する: for family in UIFont.familyNames.sorted() { let names = UIFont.fontNames(forFamilyName: family) print("Family: \(family) Font names: \(names)") }

Terminalの小技

Mac

実行を中止:Ctrl + C 入力行を削除:Ctrl + U 入力行の最後の単語を削除:Ctrl + W

Array(repeating, count)の罠

Array(repeating, count)はクラスを作成の時には使えない。 例えばArray(repeating: UIView(frame: .zero), count: 5)を書いた時実に作ったViewは一つだけ。五つのポインターは同じViewに指しているだけ。 正しいやり方は(0...4).map { _ in UIView(frame: .…

画面半分表示のModal View

iOS 15+では、新しいSafariブックマークのような画面半分表示のModal Viewが作れるようになりました。 let modalVC = ModalViewController() let modalNC = UINavigationController(rootViewController: modalVC) if #available(iOS 15.0, *) { if let sheet…

Content Hugging PriorityとContent Compression Resistance Priority

Content Hugging Priority:二つのコンテンツが並んで、十分なスペースがある場合、そのpriority高いやつはもっとタイトな形式で表示する。 例:textAのContent Hugging PriorityはtextBより大きい場合: Content Compression Resistance Priority:二つのコ…

frameとbounds

frameはsuperViewに対する位置、x, yはsuperViewによって変わる。 boundsはview自身に対する位置、x, yは常に0。 だからviewAのsubView viewBを作って、viewBはviewAを完全重合したい場合、viewB.frame = viewA.boundと書く。 因みに、viewを移動したり変形…

UIKitでStoryboardなしのアプリを作る

XcodeでUIKitのアプリを作成する。 Main.storyboardを削除する。 ProjectファイルのTarget -> General -> Deployment Info -> Main Interfaceを空欄にする。 Info.plist -> Application Scene Manifest -> Scene Configuration -> Application Session Role …

実用的なString Extension

SwiftのStringは色々な考慮上、便利なSubstring方法を提供されていない。LeetCodeをやる時Stringの問題が合うとかなり面倒くさい。下記のextensionをコピペーすれば大変助かる。 extension StringProtocol { subscript(_ offset: Int) -> Element { self[ind…

??の実行順序について

LeetCodeをやっている時バグを遭遇した。 dic[a] = dic[a] ?? 0 + 1 のようなコードを書いた時、dic[a]は常に1になってしまう。 原因は0 + 1はいつも先に実行される。 だから上記にコードは下記のように書かないといけない: dic[a] = (dic[a] ?? 0) + 1

リモートは既に削除済み、ローカルまだ残っているbranchを削除する

Git

git remote prune remote名

Dynamic Font無効化

Apple DocumentからdynamicTypeSize(_:)という関数を発見した。 下記の例はフォントタイプを強制的にxLargeに設定する: ContentView() .dynamicTypeSize(.xLarge) 下記の例はフォントタイプをlarge以下限定する: ContentView() .dynamicTypeSize(...Dynami…

実用的なBundle Extension for Jsonファイルロード

extension Bundle { func load<T: Codable>(from fileName: String) -> T? { guard let url = url(forResource: fileName, withExtension: "json") else { return nil } guard let data = try? Data(contentsOf: url) else { print("File \(fileName) does not exist.") </t:>…

実用的なFileManager Extension for Jsonファイルのセーブ/ロード

enum FileName: String { case pc case gameData } extension FileManager { func load<T: Codable>(from fileName: FileName) -> T? { let url = getDocumentsDirectory().appendingPathComponent(fileName.rawValue) guard let data = try? Data(contentsOf: url) else</t:>…

Optionalプロパティのdecode方法

例えばプロパティvar weapon: Weapon?をdecodeしよう場合、decodeIfPresentは便利です。書き方は下記です: weapon = try container.decodeIfPresent(Weapon.self, forKey: .weapon) 関連記事: cecil-it.hatenadiary.com

リモートブランチをチェックアウトする

Git

格好いい書き方: git checkout -t origin/branch1 ダサい書き方: git checkout -b branch1 origin/branch1

Proerty Wrapper @AppStorage

@AppStorage("name") private var name = "Cecil" こう書くと、name属性はUserDefaultsからデータを読み込む。またname属性を変更するとき、UserDefaultの値も更新する。

Macアプリの表示名変更

TargetのBuild Settingsの中、"product name"を検索して、その値を変更する。

layoutPriority

VStackを使う時、真ん中のtextはtruncateされることがある。 この時.layoutPriority(1)を追加すれば問題解消できる。

Git Stash

Git

変更したファイルを退避させる: git stash untrackedファイルを含めて退避させる: git stash -u コメントを残して退避させる: git stash save 'コメント' 退避リスト一覧 git stash list 退避させたファイルを戻す: git stash apply 退避させたファイル…

Simulatorの録画

xcrun simctl io booted recordVideo ファイル名.mov

多言語対応メモ

普通Stringの翻訳:Localizable.strings App表示名の翻訳:InfoPlist.stringsの中下記のように記載 "CFBundleDisplayName" = "剪贴板清除者"; 便利のLocalize拡張 extension String { func localized() -> String { return NSLocalizedString(self, comment:…

クラス、方法、パラメーターのコメント便利追加法

command + option + /