
【徒然iOS】気ままにUIKit4〜テキストフィールド、イニシャライズビュー、前処理・本処理・後処理〜
概要
さてと、
で予告してたとおり、しっかりデジタルデトックスも出来たので、
このマガジンは四十を過ぎたおっさんが、
を参考にStoryboardでiOSアプリを完全に趣味で楽しんでいるだけを今日から再開。
ちょっと、他にしたいこともあるので、今週はひとつだけかな💦
個人的に、
こういう内容を動画でやると、
コードが読みにくい
見出しで区切れないから、みたいポイントがピンポイントで見れない
みたいなことがあるから、動画ではやらないんだよね〜〜〜〜。。。
Apple公式
テキストフィールドの基本
をみながらゆっくりやってく〜〜〜〜〜!
作業に入る前に
StoryboardはXibファイルなんかと連携していて、失敗すると面倒なことになるので、、、
なんかの記事でも書いてはいるんだけど、
前準備として、
前回までのファイルを複製してバックアップを取る
をやっておこう!
*失敗したらすぐに戻せるからね〜〜〜〜〜🕺
現地では、SourceTreeとかSVNみたいなバージョン管理ツールを使っていない限り、
バックアップを取る
↓
テスト系でテストする(単体テスト、ユニットテスト)
↓
本番系にデプロイする(結合テスト)
みたいな流れは基本だから、癖つけしとくと後々面倒が減りまする!!!


では、今回の作業に入る〜〜〜〜〜!!!!!

前回がここまでで止まってるんだけど、
市販の作る系の本とかだと、
機能単体の作り方を教える
に特化してるからか、
ひとつのプロジェクトファイルにひとつの機能を追加していく教え方になってる
ことがほとんど。
でも、その教え方だと
⒈ ファイルが無限に増えていく可能性がある
⒉ 全部理解したとしても、学んだ機能をひとつのアプリに結合するやり方が載っていないから難しい
👉単体機能は作れるのに、結合した時にかえって時間がかかる
みたいなことになる人が現地でもよくいる。
(iOSの記事に興味を持って読んでるくらいだから、普段から色々なアプリを使ってる人が多いと思うけど、なかなかひとつの画面(ビュー)だけで完結してるみたいなアプリってそんなにないと思う)
なので、
まずはビューの増やし方から
右上の+をクリックして、出てくるキット集から以下を選択

で、Mainの編集領域に、下図みたいにドラッグすると、ビューがひとつ追加される

今回はテキストフィールドで遊ぶから、
元々、出来てるViewControllerファイルを開く

classから最後までをコピー

前回までに追加したSwiftファイルの最終行以降に追加

今回はテキストフィールドを使うから、クラス名を変更

追加したクラスを追加したビューに連結
Mainを開く

追加したViewControllerの上の一番左側のマークをクリック

で、Xcode右側のInspectorを開いて

ちょうど真ん中のクラス管理とかできるところを選択して、今追加したクラスファイルとさっき追加したビューを連結させる

で、ここがポイント
シミュレータとか実機でテストしたい時に、今のままだと
テストの最初に表示されるビューの指定が、前回までに使ったビューのままだから、テストしたビューに最初に表示されるビューの指定を移す。
要は、

の→が最初に表示されるビューの指定
is Initial View Controller
だから、これを変更してあげるだけ
さっき追加したビューを選択して、Inspectorの

を選択して、

にチェックを入れるだけで、

みたいな感じで、追加したビューに矢印が移った🕺
でこれを一応、シミュレータで実行してみると

こうすれば、わざわざ機能ごとにプロジェクトファイルを追加しなくても、やりたい開発がひとつのファイルでできるようになるね。
前準備はここまでだから、
今回の本題の操作をやっていこう
ラベルとテキストフィールドを配置

ラベルはOutlet
テキストフィールドはActionで接続
みたいだから接続


コードがデリゲートプロトコルを追加してるので、
コードを以下に修正できるかを試す。
class TextFieldViewController: UIViewController,UITextFieldDelegate {
@IBOutlet weak var labelTextField: UILabel!
@IBAction func textFieldEditingDidEnd(_ sender: UITextField) {
labelTextField.text = sender.text
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
シミュレータで実行
ん?変わらないぞ、、、?

で、よく見ると、アクション接続方法で選択した
Editing Did End
は、キーボードをしまうメソッドを呼び出したときにこのイベントのメソッドが呼び出される。
と書かれていて、キーボードを閉じるアクションを今回はまだそれを追加してないから実は正解なんだとわかる🕺
テキストフィールドが空白で並ぶと面倒臭いので、
それぞれの動きがわかるようにしとく
テキストフィールド選択して、

AttributionInspectorを選択

で、PlaceholderにEditing Did Endを入力

テキストフィールドにうっすら文字が表示された

で続きを読んでいくと、、、イベント処理ごとにテキストフィールドを追加した方が良さげだから、再度、ここまででバックアップを取って、イベントごとのテキストフィールドを追加してみる
Did End On Exit
アクション接続して〜〜〜〜

コードを以下に書き換えて〜〜〜
@IBAction func textFieldDidEndOnExit(_ sender: UITextField) {
labelTextField.text = sender.text
}

実機かシミュレータで試してみて〜〜〜

次は、
Editing Changed
だから、これもさっきと同じように、テキストフィールドを追加→アクション接続→。。。て感じでリアルタイムで監視ができるかを確認

@IBAction func textFieldEditingChanged(_ sender: UITextField) {
labelTextField.text = sender.text
}



さらに続きを読んでいくと、、、
キーボードを閉じる作業を入れるって書いてあるから、ここもバックアップを取ってから、コードを追加してみる〜〜〜
と、たびたびバックアップを取っていくと、すぐにファイルが肥大化していくから、個人によりけりだけど、ここまで上手く行ったファイルはゴミ箱に移動する
👉バックアップはこまめに取るが、ひとつまでにしておくと管理しやすい。
ちなみに、ここのデリゲートの考え方は、Storyboardではすごく重要だからちゃんと読んでおこう🕺
テキストフィールドにアウトレット接続も必要なようだから、追加


デリゲート先を指定するコードを追加〜〜〜
self.myTextFieldEditingDidEnd.delegate = self

で、キーボードを改行した時に閉じるメソッドを追加しろってことだから追加〜〜〜
//改行、または、Returnキーが押されたら呼び出されるメソッド
func textFieldShouldReturn(textField:UITextField) -> Bool {
//キーボードをしまう
self.view.endEditing(true)
return false
}

動くかどうかを確認〜〜〜

他はアウトレット接続をしてないからどうなるかを確認👀

同様にアウトレット接続して改善するかを確認




Editing Did Begin
あとは、こいつだけみたいなので、同様にやってく〜〜〜

今回のコード
class TextFieldViewController: UIViewController,UITextFieldDelegate {
@IBOutlet weak var labelTextField: UILabel!
@IBOutlet weak var myTextFieldEditingChanged: UITextField!
@IBAction func textFieldEditingChanged(_ sender: UITextField) {
labelTextField.text = sender.text
}
@IBAction func textFieldDidEndOnExit(_ sender: UITextField) {
labelTextField.text = sender.text
}
@IBOutlet weak var myTextFieldEditingDidEnd: UITextField!
@IBAction func textFieldEditingDidEnd(_ sender: UITextField) {
labelTextField.text = sender.text
}
@IBOutlet weak var myTextFieldEditingDidBegin: UITextField!
@IBAction func textFieldEditingDidBegin(_ sender: UITextField) {
labelTextField.text = sender.text
}
override func viewDidLoad() {
super.viewDidLoad()
self.myTextFieldEditingDidEnd.delegate = self
self.myTextFieldEditingChanged.delegate = self
self.myTextFieldEditingDidBegin.delegate = self
// Do any additional setup after loading the view.
}
//改行、または、Returnキーが押されたら呼び出されるメソッド
func textFieldShouldReturn(_ textField:UITextField) -> Bool {
//キーボードをしまう
self.view.endEditing(true)
return false
}
}
デザインもちょっと磨き上げ

今回のまとめ
何かの変更をする前にバックアップを取る
Initial View Controllerの使い方を知っておくと、プロジェクトファイルを新規作成しなくても、やりたいテストができる
クラス管理ファイルをひとつ設けておくだけで、接続ファイルの数が減らせる
以上かな。
ゆっくり丁寧に画面採取しながらやったから、すっげ〜〜〜長くなったけど💦
趣味でやってはいるけど、読みながら動かしてもらえれば、自然と開発現場に必要な素養とか考え方が身に付くようになればなあと思ってるので💦💦
しっかし、準備→開発→検証は本当に大事な基本だなあ。
さてと、
嫁が帰ってくるので、今からランチの準備🕺
今日はミートソースを作ってボロネーゼ🍝
ランチ後の追記
ちょっとXcodeのアップデートが始まって時間がかかってるので💦
最近よく、
プログラミングを勉強する意味
みたいな記事を目にするんだけど、最初から意味なんて求めても
で、書いたとおりその言語で出来る機能を知らないと、却ってモチベーションは下がるかなと。
そんなご大層な目的とか、自分が学ぶ意味みたいなプラグマティズムに考えなくて、今回のテキストフィールドで言えば、
「ああこれが、氏名や住所、メールアドレスみたいなアカウント登録画面な感じで使われてるのか。」
「これって、自分が作りたいアプリの〇〇に使えそうだなあ。」
て視点で見といてもらえると、長期記憶になったり、じゃあ実際作ってみよって感じで応用しやすくなるかなと。
💃どんな大きなシステムやアプリも分解していけば、
所詮は、小さなコードのかたまり🕺
だからね。
やっぱり、
プログラミングや開発は楽しい😋
💃やる意味なんか最初から求めずに、まずはゆっくり気軽にやるのが近道🕺
習熟した人ならば、できて当たり前だろうし、もっと良いやり方がもちろんあるんだけどね。
でも書いてるけど、
ハイテクと使いやすいて結構結びつかない
例えば、今回追加したテキストフィールドにしろ、前回のボタンにしろ、
ビューを開いた瞬間に、Placeholderとかボタン名にどんな動きをするものかが使う人が見た瞬間にわかるようにしとかないと、
アクションシートの説明が必要になったり、覚えることが増えて使われなくなったりする。
使いやすさ=わかりやすさ=おもいやり
👉それを
ユーザビリティ
て言ったりするんだよね〜〜〜〜
とまあ、偉そうなことは言えないし、わかんないけど。