Swiftで遊ぼう! on Hatena

あしたさぬきblogでやってた初心者オヤジのiOSプログラミング奮闘記がHatenaに来ました

Swiftで遊ぼう! - 980 - 過去記事の修正

ググって調べている情報サイトの内容がかなり理解できるようになっています! 我ながら驚きです。地道に勉強を続けていた成果がやっと出てきているって感じですね。

トーリーボードの部品としてカスタムViewの作り方も理解できました!

xib」ってなんて読むのでしょう?

私は「エクシブ」って読みましたが調べていると「ジブ」って読むのが正解?

とりあえず以下の記事を少し修正しました。

yataiblue.hatenablog.com

今日はこれだけ。

Swiftで遊ぼう! - 979 - iOS開発関連サイト:リンク集

カスタムViewを用意するためにネットを色々調べていると有益なサイトが増えていることに気がつきました。私が勉強をはじめた頃はほとんど無かったんですが、iOS開発に興味をしめす人が多いってことですね。役に立ちそうなサイトを備忘録として記録します。

日本語サイト

プログラミング質問サイト

英語サイト

共有サイト

Swiftで遊ぼう! - 979 - UITextFieldのプロパティ: inputView

オリジナルアプリ作りに奮闘中!

誕生日データを入力するためにオリジナルのポップオーバーを使ったら便利だと思って実装しました。

f:id:yataiblue:20170502181940j:plain

ところが読者のberrymuchさんから「iOSヒューマンインターフェイスガイドライン」に準拠していないという指摘をうけました(T_T)

どうせ作るならAppStoreで受け入れられるアプリを作りたいのでガイドラインに準拠させていくことにします。

ユーザーからの入力は基本、キーボードを使用するようになっています。するとシステムで用意されていないキーボードを使用したい場合、カスタムキーボードを用意しなきゃいけないのかなって最初は思いました。

しばらくググって調べてみると、UITextFieldの場合、標準キーボードの代わりにUIViewクラスの「inputView」が利用できることがわかりました。それに加え「inputAccessoryView」を使えばUIToolbarも実装できます。iPhoneiPadのどちらでも同じように使用できるんで、ポップオーバーの実装をそのままinputViewに変更しました。

f:id:yataiblue:20170518174058j:plain

しかし、1つだけ問題があります。iPadではiPhoneで存在しない謎のメニューがUIToolbarとUIDatePickerの間に出現します。

f:id:yataiblue:20170518175035j:plain

これをどうやったら隠すことができるんでしょうか?

とりあえず見た目は同じにできましたがまだ実装が追いついていません。というのもinputViewのデザインをすべてコードでしないといけないんで、NumpadViewの実装も大変なんです。

たぶん、ストーリーボードを使ってデザインできると思うので、もう少しInterface Builderの使い方も勉強した方がよさそうですね...

Swiftで遊ぼう! - 978 - 今頃ですがWWDC 2016のビデオ観てます(^_^;)

来月はWWDC 2017が開催される予定です。

新しいiPad Proの発売の噂もあるんで楽しみにしていまが、またiOSフレームワークやSwiftに変化が加わるんでついていくのが大変です。復習という訳じゃなく、アプリのデザインの関連する項目をWWDC 2016のビデオから選択して観ています。

iPad向けのアプリを作っているんですが、iPhoneにも対応できているのが基本のようなので「Making Apps Adaptive, Part 1」で勉強しました。

developer.apple.com

今日のビデオのポイントは次のメソッドです。

traitCollectionDidChange(:)

しかしながら、Xcode 8のInterface Builderを使っているかぎり、このコードを意識する必要がないんです。すべて自動で設定してくれるんです。

The system is going to do most of the work so you don't have to.

ということで、Xcode 8のサイズクラスの使い方をブラッシュアップしました。

これだけ。

Swiftで遊ぼう! - 977 - Good design is not easy

WWDC 2017が来月開催されるというのに私はWWDC 2016のビデオを見て勉強しています。昨日berrymuchさんからiOSユーザーインターフェイスガイドラインの説明を受けたので次のビデオを見ました。

developer.apple.com

おおお、なんとKeynoteでデザインしているんですね。Keynoteは私もプレゼンテーションで使いまくっているので慣れています。これから作るアプリもKeynoteを使ってデザインしてみます。KeynoteのデザインをKeynoteでするほどアップルの人間はKeynote好きなんですね。

Design mattersです。やっぱりデザインの勉強もしないといけませんね。

ということで今日からデザインに目覚めます(笑)

では。

Swiftで遊ぼう! - 976 - セグエに関するコメントの返事

久しぶりに下記のエントリーにコメントが入りました!

私がブログを続けている理由の1つは読者からのコメントです。berrymuchさん、本当にありがとうございます!

yataiblue.hatenablog.com

今日の記事は上記ブログの内容の続きです。

berrymuchさんから2つ指摘を受けました。まず最初のprepareメソッドに関して詳しく説明します。

私の理解している範囲でセグエの説明をします。

セグエのインスタンス化には以下の2つの方法があります。

  1. トーリーボードで視覚的に生成(Ctrl + ドラッグ)
  2. コードで生成(performSegueを書く)

このどちらを利用してセグエを生成しても、遷移先のViewController生成メソッドは「prepare(for segue: UIStoryboardSegue, sender: Any?) 」です。そのため、このメソッドをoverrideしなければいけません。

私は最初に、ストーリーボードで視覚的にセグエを設定しました。つまりTextFieldから「Ctrl + ドラッグ」して遷移先のViewControllerに繋いで、Identifierの設定をしたということです。

そして遷延元のViewControllerに次のコードを加えました。

override func prepare(for segue:UIStoryboardSegue, 
                         sender:Any!) {
        
    if let identifier = segue.identifier {
        switch identifier {
        case "Show Datepopover":
             if let dateController = segue.destination 
                                as? DatePopoverController {
                 dateController.delegate = self
                 let widthX = birthTextField.bounds.midX
        
                 if let popoverController = 
                        dateController.popoverPresentationController {
                     popoverController.delegate = self
        
                     popoverController.sourceRect = 
                         CGRect(x: widthX, 
                                y: self.view.frame.minY + 30, 
                            width: 0, 
                           height: 0)
                 }
        
             }
         case "Show Numpadpopover":
             if let numpadPopover = 
                    segue.destination as? NumpadViewController {
                  numpadPopover.delegate = self
        
                  let widthX = idField.bounds.midX
        
                  if let popoverController = 
                      numpadPopover.popoverPresentationController {
                      popoverController.delegate = self
        
                      popoverController.sourceRect = 
                            CGRect(x: widthX, 
                                   y: self.view.frame.minY + 30, 
                               width: 0, 
                              height: 0)
                  }
              }
        
        
          default:
               break
           }
      }
}

これでシュミレーションを実行させてテキストフィールドをタッチすると、デフォルトのキーボードが出現するんです。このデフォルトのキーボードをマニュアルで閉じると遷移先ののPopoverが出現します。

どうしてもデフォルトのキーボードが最初に立ちあがるのを止めることができません。色々試していて上手く動いたのが先日お話したperformSegueの利用だったと言うわけです。

デフォルトのキーボードの消し方も色々あることは分かりました。resignFirstResponder()textFieldShouldBeginEditing(_ textField: UITextField)を色々使って、試していたらperformSegueで上手く動いたということです。

キーボードの制御に関して考えていると、berrymuchさんの2つめのアドバイスで「は!」と気がつきました。私の考えているデザインは、インターフェイスガイドラインに全く準じていませんでした。

ユーザインターフェイスのデザインのヒント - Apple Developer

このページも全く知らなかったです。berrymuchさん、情報ありがとうございます。

カスタムPopoverを使おうと考えたのは、私のアプリはiPad専用を考えていたからです。iPhoneで「Number Pad」を利用すれば数字だけの入力ができるのですが、iPadでは「Number Pad」の利用ができません。そこで独自にPopoverからの入力を思いついた訳です。

しかし、ガイドラインを読むと、そういう勝手なインターフェイスは許されていないようですね。「TextFieldからPopoverのコントロールガイドライン違反」と考えていいんでしょう。それで実装しにくいんじゃないかと思います。

そして思いついたんです。iPadで用意されていないのならカスタムキーボードを用意して入力すればガイドラインに準じていると思いました。

berrymuchさんのコメントでまた少し成長できました。ありがとうございました。

通りすがりの読者の皆さん、何でもいいのでコメントをお願いしますm(_ _)m

では。

Swiftで遊ぼう! - 975 - Numpad Popoverの実装に関して

誕生日を入力するためのDate PopoveはViewControllerに値を渡さないといけないのでProtocolを用意しました。ViewControllerはこのプロトコールに準拠することで値を表示することができます。このやり方だと準拠すべきプロトコールがクラス宣言の後に並びます。UITextFieldDelegateやUIPopoverPresentationControllerDelegateも並ぶので長々しく見た目はよくありません。

カスタムPopoverを1つ作るたびにProtocolに準拠させるというコーディングスタイルは正しいのでしょうか?かなり疑問に思っています。

Numpad Popoverという新たなカスタムPopoverを用意しました。この入力値をViewControllerに渡すためにProtocolを用意しました。渡す値の型もDate Popoverと異なるので共通化はできないと思います。ということで今回はExtensionを使ってみました。

f:id:yataiblue:20170513212240j:plain

Numpad Popoverで数字をタップするとリアルタイムにテキストフィールドに表示されるようにできました。

こういう場合Protocolに準拠させるのとExtensionを追加するのとどちらがふさわしいのでしょう?

悩みはつきません(^_^;)