- 投稿日:2021-10-22T23:53:42+09:00
UITextField 入力値が連番だった場合アラート表示
今回の内容 コードと簡単解説 func judge(judgeTarget:String){ if Int(judgeTarget.prefix(2).suffix(1)) == Int(judgeTarget.prefix(1))! + 1 && Int(judgeTarget.prefix(3).suffix(1)) == Int(judgeTarget.prefix(2).suffix(1))! + 1 && Int(judgeTarget.suffix(1)) == Int(judgeTarget.prefix(3).suffix(1))! + 1{ alert() }else if Int(judgeTarget.prefix(2).suffix(1)) == Int(judgeTarget.prefix(1))! - 1 && Int(judgeTarget.prefix(3).suffix(1)) == Int(judgeTarget.prefix(2).suffix(1))! - 1 && Int(judgeTarget.suffix(1)) == Int(judgeTarget.prefix(3).suffix(1))! - 1{ alert() }else if judgeTarget.prefix(1) == judgeTarget.prefix(2).suffix(1) && judgeTarget.prefix(1) == judgeTarget.prefix(3).suffix(1) && judgeTarget.prefix(1) == judgeTarget.suffix(1){ alert() } 入力値が1234の場合 一番上のif文の対象になります。 まずは、2文字目を取得してきます。取得した2文字目が1文字目の値に+1をした値と等しい場合は1文字目と2文字目が連番だと確認できます。 次は、3文字目を取得してきます。取得した3文字目が2文字目の値に+1をした値と等しい場合は2文字目と3文字目が連番だと確認できます。 次は、4文字目を取得してきます。取得した4文字目が3文字目の値に+1をした値と等しい場合は3文字目と4文字目が連番だと確認できます。 入力値が4321の場合 2番目のelse if文の対象になります。 まずは、2文字目を取得してきます。取得した2文字目が1文字目の値に-1をした値と等しい場合は1文字目と2文字目が連番だと確認できます。 次は、3文字目を取得してきます。取得した3文字目が2文字目の値に-1をした値と等しい場合は2文字目と3文字目が連番だと確認できます。 次は、4文字目を取得してきます。取得した4文字目が3文字目の値に-1をした値と等しい場合は3文字目と4文字目が連番だと確認できます。 入力値が1111の場合 3番目のelse if文の対象になります。 まずは、1文字目を取得してきます。取得した1文字目と2,3,4文字目が同じ値であるかを確認します。 全てのコード import UIKit class ViewController: UIViewController { @IBOutlet weak var textField: UITextField! override func viewDidLoad() { super.viewDidLoad() textField.addTarget(self, action: #selector(judgeText), for: .editingChanged) } @objc func judgeText(sender:UITextField){ if sender.text?.count == 4{ judge(judgeTarget: sender.text!) } } func judge(judgeTarget:String){ if Int(judgeTarget.prefix(2).suffix(1)) == Int(judgeTarget.prefix(1))! + 1 && Int(judgeTarget.prefix(3).suffix(1)) == Int(judgeTarget.prefix(2).suffix(1))! + 1 && Int(judgeTarget.suffix(1)) == Int(judgeTarget.prefix(3).suffix(1))! + 1{ alert() }else if Int(judgeTarget.prefix(2).suffix(1)) == Int(judgeTarget.prefix(1))! - 1 && Int(judgeTarget.prefix(3).suffix(1)) == Int(judgeTarget.prefix(2).suffix(1))! - 1 && Int(judgeTarget.suffix(1)) == Int(judgeTarget.prefix(3).suffix(1))! - 1{ alert() }else if judgeTarget.prefix(1) == judgeTarget.prefix(2).suffix(1) && judgeTarget.prefix(1) == judgeTarget.prefix(3).suffix(1) && judgeTarget.prefix(1) == judgeTarget.suffix(1){ alert() } } func alert(){ let alert = UIAlertController(title: "連番です", message: "連番だけど大丈夫かな?", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)) alert.addAction(UIAlertAction(title: "キャンセル", style: .cancel, handler: nil)) self.present(alert, animated:true, completion: nil) } } 終わり もう一つパターンがあるのでそれについても、明日以降に投稿したいと思います。 ご指摘、ご質問などありましたら、コメントまでお願い致します。
- 投稿日:2021-10-22T23:53:42+09:00
UITextField 入力値が連番だった場合アラート表示(4文字)
今回の内容 コードと簡単解説 func judge(judgeTarget:String){ if Int(judgeTarget.prefix(2).suffix(1)) == Int(judgeTarget.prefix(1))! + 1 && Int(judgeTarget.prefix(3).suffix(1)) == Int(judgeTarget.prefix(2).suffix(1))! + 1 && Int(judgeTarget.suffix(1)) == Int(judgeTarget.prefix(3).suffix(1))! + 1{ alert() }else if Int(judgeTarget.prefix(2).suffix(1)) == Int(judgeTarget.prefix(1))! - 1 && Int(judgeTarget.prefix(3).suffix(1)) == Int(judgeTarget.prefix(2).suffix(1))! - 1 && Int(judgeTarget.suffix(1)) == Int(judgeTarget.prefix(3).suffix(1))! - 1{ alert() }else if judgeTarget.prefix(1) == judgeTarget.prefix(2).suffix(1) && judgeTarget.prefix(1) == judgeTarget.prefix(3).suffix(1) && judgeTarget.prefix(1) == judgeTarget.suffix(1){ alert() } 入力値が1234の場合 一番上のif文の対象になります。 まずは、2文字目を取得してきます。取得した2文字目が1文字目の値に+1をした値と等しい場合は1文字目と2文字目が連番だと確認できます。 次は、3文字目を取得してきます。取得した3文字目が2文字目の値に+1をした値と等しい場合は2文字目と3文字目が連番だと確認できます。 次は、4文字目を取得してきます。取得した4文字目が3文字目の値に+1をした値と等しい場合は3文字目と4文字目が連番だと確認できます。 入力値が4321の場合 2番目のelse if文の対象になります。 まずは、2文字目を取得してきます。取得した2文字目が1文字目の値に-1をした値と等しい場合は1文字目と2文字目が連番だと確認できます。 次は、3文字目を取得してきます。取得した3文字目が2文字目の値に-1をした値と等しい場合は2文字目と3文字目が連番だと確認できます。 次は、4文字目を取得してきます。取得した4文字目が3文字目の値に-1をした値と等しい場合は3文字目と4文字目が連番だと確認できます。 入力値が1111の場合 3番目のelse if文の対象になります。 まずは、1文字目を取得してきます。取得した1文字目と2,3,4文字目が同じ値であるかを確認します。 全てのコード import UIKit class ViewController: UIViewController { @IBOutlet weak var textField: UITextField! override func viewDidLoad() { super.viewDidLoad() textField.addTarget(self, action: #selector(judgeText), for: .editingChanged) } @objc func judgeText(sender:UITextField){ if sender.text?.count == 4{ judge(judgeTarget: sender.text!) } } func judge(judgeTarget:String){ if Int(judgeTarget.prefix(2).suffix(1)) == Int(judgeTarget.prefix(1))! + 1 && Int(judgeTarget.prefix(3).suffix(1)) == Int(judgeTarget.prefix(2).suffix(1))! + 1 && Int(judgeTarget.suffix(1)) == Int(judgeTarget.prefix(3).suffix(1))! + 1{ alert() }else if Int(judgeTarget.prefix(2).suffix(1)) == Int(judgeTarget.prefix(1))! - 1 && Int(judgeTarget.prefix(3).suffix(1)) == Int(judgeTarget.prefix(2).suffix(1))! - 1 && Int(judgeTarget.suffix(1)) == Int(judgeTarget.prefix(3).suffix(1))! - 1{ alert() }else if judgeTarget.prefix(1) == judgeTarget.prefix(2).suffix(1) && judgeTarget.prefix(1) == judgeTarget.prefix(3).suffix(1) && judgeTarget.prefix(1) == judgeTarget.suffix(1){ alert() } } func alert(){ let alert = UIAlertController(title: "連番です", message: "連番だけど大丈夫かな?", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)) alert.addAction(UIAlertAction(title: "キャンセル", style: .cancel, handler: nil)) self.present(alert, animated:true, completion: nil) } } 終わり もう一つパターンがあるのでそれについても、明日以降に投稿したいと思います。 ご指摘、ご質問などありましたら、コメントまでお願い致します。
- 投稿日:2021-10-22T23:38:53+09:00
【Swift】APIキー専用の構造体を作って管理する方法
Swiftで大事なAPIキー専用の構造体を作って管理する方法。 大事なAPIキーをまとめた構造体を作ってファイルに書いておけば、GitHubなどで公開する際に、そのファイルだけ.gitignoreで除外しておけば、漏れる心配もないので安心。 APIキーを集約した構造体 import Foundation struct ImportAPI { public static let API_KEY = "xxxxxxxxxxxxxxxxxxxx" public static let API_TEST_KEY = "xxxxxxxxxxxxxxxxxxxx" } APIを呼び出す時のコード print(ImportAPI.API_KEY) print(ImportAPI.API_TEST_KEY)
- 投稿日:2021-10-22T23:23:40+09:00
【Swift】UIAlertControllerを簡単に実装する関数
毎回3~4行必要とするUIAlertControllerを簡単に実装する関数を作ったのでメモとして残しておきます。 変更前 実装するUIAlertControllerに搭載されているボタンはOKボタンのみです。(汎用性が高いので) let alert = UIAlertController(title: "UIAlertControllerのタイトル", message:"UIAlertControllerのテキストメッセージ", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil)) self.present(alert, animated: true, completion: nil) 変更後 一度関数を宣言したら、後は毎回self.showAlert(title: "タイトル", text: "メッセージ")を呼び出すだけ。 // 関数 func showAlert(title : String , text : String){ let alert = UIAlertController(title: title, message: text, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil)) self.present(alert, animated: true, completion: nil) } //実際に呼び出す時 self.showAlert(title: "タイトル", text: "メッセージ")
- 投稿日:2021-10-22T20:38:19+09:00
【Swift】UINavigationControllerのカスタマイズ設定
NavigationBarの表示・非表示 // 非表示にする。 navigationController?.navigationBar.isHidden = true // false 表示 // viewをタップで表示・非表示を切り替える。 navigationController?.hidesBarsOnTap = true // viewをスワイプで非表示にする。 ※もう一度スワイプしても非表示のまま。 navigationController?.hidesBarsOnSwipe = true // デバイスを横向きに回転させると非表示になる。 navigationController?.hidesBarsWhenVerticallyCompact = true // キーボードを起動で非表示になる。 ※キーボードを閉じても非表示のまま。 navigationController?.hidesBarsWhenKeyboardAppears = true NavigationBarのカスタマイズ タイトル設定 // タイトル名の設定。 navigationItem.title = "タイトル名" // タイトルの色設定。 navigationController?.navigationBar.titleTextAttributes = [ .foregroundColor: UIColor.blue ] // タイトルに画像を配置する設定。 *位置はサイズにて調節して下さい。 let imageView = UIImageView(image: UIImage(named: "image_name")) imageView.contentMode = .scaleAspectFit navigationItem.titleView = imageView ボタン設定 // 戻るボタンのテキストを非表示にする場合。テキストを変更する場合は""の間に任意のテキストを入れて下さい。※必ず遷移元のViewControllerに記載する!!! navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil) // iOS14以上で戻るボタンのテキストを非表示にしたい場合はこちら。 ※必ず遷移元のViewControllerに記載する!!! navigationItem.backButtonDisplayMode = .minimal // NavigationBarItemの色の設定。 navigationController?.navigationBar.tintColor = UIColor.blue // NavigationBarItemに画像を配置する設定。 *位置はサイズにて調節して下さい。 let image = UIImage(named: "image_name") navigationController?.navigationBar.backIndicatorImage = image navigationController?.navigationBar.backIndicatorTransitionMaskImage = image バーの設定 // スタイル設定 白いすりガラスの様な半透明の背景に黒い文字。 navigationController?.navigationBar.barStyle = .default // デフォルト // スタイル設定 黒いすりガラスの様な半透明の背景に白い文字。 navigationController?.navigationBar.barStyle = .black // 半透明な背景を辞めたい場合。 navigationController?.navigationBar.isTranslucent = false // NavigationBarの背景設定。 ※半透明にならない。 navigationController?.navigationBar.barTintColor = UIColor.blue // NavigationBarの背景画像の設定 ※半透明化可能。 self.navigationController?.navigationBar.setBackgroundImage(UIImage(named: "image_name.jpg"), for: .default) // NavigationBarを透過する。 navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default) navigationController?.navigationBar.shadowImage = UIImage() おまけ // 画面をスワイプをしても前画面に戻らなくなる。 navigationController?.interactivePopGestureRecognizer?.isEnabled = false
- 投稿日:2021-10-22T18:17:22+09:00
[SwiftUI] どうせなら、かっこよく、Glassmorphism
はじめに SwiftUIはカスタマイズも簡単なので、色々なUIデザインを試してみることができます。そこで今回はGlassmorphism風のUI作りを紹介していきます。 Glassmorphismって? 簡単にいうと、すりガラス風のUIのことです。こちらのサイトはCSS用のものですが見ていただければ大体のイメージはつかんでもらえるかと思います。 Glassmorphism CSS Generator できたもの まずは完成品をご覧ください。プロのデザイナー!というわけではないのでちょっと不十分なところもありますが、SwiftUIだけでとりあえずこんなものができます。 コードと使い方 半透明の背景 GlassBackGround.swift import SwiftUI struct GlassBackGround: View { let width: CGFloat let height: CGFloat let color: Color var body: some View { ZStack{ RadialGradient(colors: [.clear, color], center: .center, startRadius: 1, endRadius: 100) .opacity(0.6) Rectangle().foregroundColor(color) } .opacity(0.2) .blur(radius: 2) .cornerRadius(10) .frame(width: width, height: height) } } RadialGradientとRectangleを重ね、透明度もちょっとずらしています。もう少しスマートな解決法があるような気もしますが、色々と試行錯誤した結果、これが一番上のサイトのような見た目に近くなりました。 使い方 GlassView.swift import SwiftUI struct GlassView: View { var body: some View { VStack { Image(systemName: "person.circle") .font(.largeTitle) Text("Glass") }.foregroundColor(.white) .background( GlassBackGround(width: 100, height: 100, color: .black) .shadow(color: .black, radius: 2, x: 2, y: 2) ) } } 背景をグラデーションにしたり、パターンの模様をつけておいたりすると透けている感じがよくわかります。GlassPlaceHolderの上に表示するものには影をつけていませんが、これは上記のサイトの見本を参考にしたものです。 まとめ SwiftUIそのままよりも格段にカッコイイデザインになりました。アプリの背景やUIの配置によって細かい設定を変えた方が良い時もありますが、大体は上のコードくらいで対応できそうです。 立体感のある画面を作れるのがGlassmorphismのいいところで、個人的には結構お気に入りです。みなさんもぜひ挑戦してみてください。 作成中のアプリなどは以下に掲載しているので、よかったらこちらもよろしくお願いします☺️ Twitter note
- 投稿日:2021-10-22T16:34:20+09:00
iOS15でAirPrintの印刷処理でエラーが発生するようになったので対策する
iOS15に上げると印刷を行う処理でアプリがクラッシュするようになった 参考) https://developer.apple.com/forums/thread/689876 UIPrintInteractionControllerを使うことで、iOSのアプリからプリンターに印刷指示を出すことができるようになりますが、iOS15にアップデートするとアプリがクラッシュするようになりました。 UIPrintInteractionControllerでは、 ①予め設定しておいたプリンタの情報を渡すことで自動で印刷する方法 ②iOS標準のプリンタ設定画面を挟んで、そこで印刷指示する方法 があります。 今回はこの①の場合にクラッシュすることを確認しています。 そこで不本意ではありますが、①→②の方法に変更して一旦凌ぐことにしました。 実際のコード修正(swift) ①予め設定しておいたプリンタの情報を渡すことで自動で印刷する方法 UIPrintInteractionController func print(to printer: UIPrinter, completionHandler completion: UIPrintInteractionController.CompletionHandler? = nil) -> Bool ↓ ②iOS標準のプリンタ設定画面を挟んで、そこで印刷指示する方法 UIPrintInteractionController func present(animated: Bool, completionHandler completion: UIPrintInteractionController.CompletionHandler? = nil) -> Bool 実際のコード修正(objective-c) ①予め設定しておいたプリンタの情報を渡すことで自動で印刷する方法 UIPrintInteractionController - (BOOL)printToPrinter:(UIPrinter *)printer completionHandler:(nullable UIPrintInteractionCompletionHandler)completion; ↓ ②iOS標準のプリンタ設定画面を挟んで、そこで印刷指示する方法 UIPrintInteractionController // iPhoneの場合 - (BOOL)presentAnimated:(BOOL)animated completionHandler:(nullable UIPrintInteractionCompletionHandler)completion; // iPadの場合 - (BOOL)presentFromRect:(CGRect)rect inView:(UIView *)view animated:(BOOL)animated completionHandler:(nullable UIPrintInteractionCompletionHandler)completion; まとめ そもそも根本解決できていおらず、緊急措置的な意味合いが強い対応をしました。 修正方法でもっといい方法あるよという情報をお持ちの方はコメントお待ちしています!
- 投稿日:2021-10-22T13:28:15+09:00
【Swift】ナビゲーションバーの右に閉じるボタンを設置
Swiftでナビゲーションバーの右上に閉じるボタンを設置する方法。 //ボタンの実装 let next = NextViewController() next.navigationItem.rightBarButtonItem = { let btn = UIBarButtonItem(barButtonSystemItem: .close, target: self, action: #selector(self.onPressClose(_:))) return btn }() let nav = UINavigationController(rootViewController: next) self.present(nav, animated: true, completion: nil) 次にボタンが押された時に処理されるonPressCloseの中身を実装。 //閉じる処理を書いた関数 @objc func onPressClose(_ sender : Any){ self.dismiss(animated: true, completion: nil) } barButtonSystemItem: .closeは標準で搭載されているものから選べる。 close以外の種類を選びたい方は以下の記事がおすすめ。
- 投稿日:2021-10-22T07:51:55+09:00
Chain of Responsibility デザインパターン
チェーンオブレスポンシビリティ このデザインパターンはGoFのデザインパターンの内の一つである。「誰が何をするか」という責任を鎖のように 繋がれている状態のことである。 例えると、会社の決済のように課長で判断できなかったら部長へ、部長で判断できなかったらその上へ、と言ったように「誰が決済の判断をするか」ということをどんどん委ねていくイメージ。もし誰も行わなかったら何もしない。 メリットとしては誰が処理をするのかを一つに決めないので処理を柔軟に回すことができる。ただ、責任がどこにあるのかを探索するので処理速度が遅くなるらしい。柔軟性か即効性かで目的別に分ける必要がある。 Swiftではどういう時に使用されるか? SwiftではUIRespondarオブジェクトが管理している。 ユーザーの操作を UIButton⇨UIView⇨UIWindow⇨UIApplication(UIViewControllerはUIViewに割り込む形で入っていく。) 例 //決済を求めるプロトコル public protocol RequestSettlement { //決済する関数 func settlement(request: Any) //次の責任者を渡して初期化する init(next: RequestSettlement?) public class Settlement<T>: RequestSettlement, CustomStringConvertible { //自分の次の責任者。nilの場合は、自分自身が最後の責任者となってしまう private var nextHandler: RequestSettlement? //上のプロパティで宣言したnextHandlerをを初期化 public init(next: RequestSettlement?) { self.nextHandler = next } //ジェネリクスで渡した型Tを実際に決済できるか調べて処理する関数 public func settlement(request: Any) { if request is T { print("決済したのは\(self)だよ") } else { //処理が行われずレスポンダーチェインの最後まで到達した場合 guard let handler = self.nextHandler else { print("レスポンダーチェインが終了したよ") return } //次の責任者に送る場合 print("\(self)では決済できないから,次の責任者である\(handler)に渡すよ") handler.settlement(request: request) } }