MILLEN BOX

音楽好きの組み込みソフトエンジニアによるプログラミング(主にiOSアプリ開発)の勉強の記録

tableView(_:didSelectRowAt:) が呼ばれない場合の原因について調べてみた

私、今まで作成したアプリではあんまりTableViewって使ったことないですが、最近久しぶりに触る機会がありました。

ableViewを使用する場合、ViewControllerにUITableViewDataSourceとUITableViewDelegateを追加して、numberOfRowsInSectionやcellForRowAtなどのデリゲードメソッドを追加しますよね。
ここまでは大丈夫。

そこで、「あ、そうそう。Cellタップしたら「〜」をできるようにしなきゃ」と思い、tableView(_:didSelectRowAt:)を追加しました。
呼ばれるかどうか一応確かめるかーってので、とりあえず中の処理に print("\(#function) is called!") か何かか書いて呼び出し確認をしてみました。

そしたら、、、呼ばれてない。。。何で!?

ということで原因を調べて見ました。

原因1: UITableViewDelegateを追加していない

かなり初歩的ですが、UITableViewDelegateをUIViewControllerに追加していない場合は勿論tableView(_:didSelectRowAt:)は呼ばれません。というかビルドも通らないよね。
私の場合、前述の通りこれについては実行済みでした。

原因2: Selectionが「No Selection」

StoryboardでTable Viewを選択し、Attributes Inspector→Table View→Selectionが「No Selection」になっていないかを確認して下さい。
No Selectionだと、Cellの選択が出来ないのでそもそもtableView(_:didSelectRowAt:)が呼ばれる訳がありません。
「No Selection」を「Single Selection」に変更しましょう。

f:id:anthrgrnwrld:20171026201039j:plain

ネットを調べた限り、これが原因で問題が発生しているケースが多そうでした。
しかし私の問題はこれでは解決しませんでした。

原因3: sampleTableView.delegate = self

UITableViewDelegateを追加した場合には、当然誰に処理を委任するのか指定してあげないと行けないですよね。
この場合だと通常、sampleTableView.delegate = self でOKかと思います。
これもかなり初歩的は部分です。
当然、やってま…..ん??

うそ?やってない!?

まさかね。。。これとは。。。
かなり初歩的ですが、初歩的すぎて逆に見つけられないという。
(言い訳)

当たり前のことから見直さないとだめですね。。。

Swift4 + Xcode9環境にてUIImageViewの画像が表示されなくなっって一瞬戸惑った話

先日初心者の人にiOSアプリの作成方法を軽くレクチャーすることがあったんですよ。

手始めにStoryboardにてUILabelを貼り付けてテキストの内容を変更したり、
それをコードと関連付けしてプログラムでテキスト内容を変化させたり、
UIButtonを追加して、ボタンを押すことで内容を変化させるようなアプリを作ったりして、簡単な説明をしました。

そして、「画像も表示出来るんだよ~」ってことで、StoryBoardにてUIImageViewを追加し、お手軽にAttribute InspectorでXcodeに放り込んだjpgファイルを指定してSimulatorで実行しました。

そしたら...指定した画像が出ないんです!!!
レクチャーしてる時にこれは焦りました。。。

結構時間かけて、あーでもないこーでもないしたんですが、結局Google先生に問いただしました。
調べてみると、画像ファイルにてTargetのチェックボタンを追加するフェーズが追加されているんですね。。。。

こんな感じでボックスにチェックを追加することを忘れないようにしてください。
f:id:anthrgrnwrld:20171021071049j:plain

今までも音声ファイルなんかを入れたいときに同じ罠にはまってましたが、
今まで幾度となく追加してきたUIImageViewで同じことが起こってしまうとは。。。
これは忘れるよ。。。

皆様もご注意ください。。。

- [UIApplication delegate] must be used from main thread only

前回に引き続きswift4への対応について書きます。

既存アプリに対するマイグレーションを経た一連の対応後、下記のようなエラーが出てきました。

UI API called from background thread: 
-[UIApplication delegate] must be used from main thread only

わっかんないけど、またランタイムとかその辺のこと?とか疑いながらググりましたがすぐに出てきましたね。↓

starhoshi.hatenablog.com

私の環境の場合、Firebaseは入っておらず、AdMob環境のみでしたが、バッチリこれに当たっておりました。

上記エラーが出た際には、一先ず使用しているライブラリのアップデートをおすすめします!

​ #selector がswift4では使えない? → 使えます

​ みなさんiOS11対応してますか?
私はやっとチョビチョビと始めましたよ。

今回はiOS10で動かしていたswift3ソースを初めて開き、自動変換した時にぶつかった疑問をメモしておきます。
Xcode9を起動してswift3以前のソースを開くとXcodeマイグレーションしてくれます。

そうすると今まで一部にしかついていなかった@objc記述子が#selectorで呼ばれている全てのメソッドの頭につきます。
これでおしまいかと思いきや、ビルドするとこんな警告が出るのです。

The use of Swift 3 @objc inference in Swift 4 mode is deprecated. 
Please address deprecated @objc inference warnings, test your code 
with “Use of deprecated Swift 3 @objc inference” logging enabled, 
and then disable inference by changing the "Swift 3 @objc Inference" 
build setting to "Default" for the "bluerer" target.

Google翻訳さんの助けを借りて自分なるに翻訳しますと、

Swift4にてSwift3の@objc推論を使用することは非推奨です。
推奨されない@objc推論の警告に対処してください。
対処方法としては、「非推奨のSwift 3 @objc推論の使用」ロギングを有効にし、
ターゲットの "Swift 3 @objc Inference"ビルド設定を "Default"に変更して推論を無効にします。

@objcを使ったやり方はswift4では非推奨です、と書いているように見えます。

うーん、、、どういうこと?対処方法はあるみたいだけど?

swift4では@objcを使ったselector呼び出しを使うのが非推奨なの?

上記について、正確に理解しているわけではないのですが、非推奨になったわけではないようです。
Build settingsのSwift 3 @objc inferenceの設定をOnからDefaultへ変更することで対処可能ですが、これがAppleが推奨する形になったと考えて良さそうです。
プロジェクト→Build settingsに進んで、そこの検索窓に「Swift 3 @objc inference」と打てばすぐに出てきます。

f:id:anthrgrnwrld:20171003082420p:plain  この方法についてある方に
「非推奨な使い方にも関わらず、設定で警告が消えてしまうことに違和感を感じる」
と伝えたところ、

@objc自体が非推奨になったわけじゃないみたい。
Swift3のときはXcodeが自動的に@objcをつけてくれてたけど、
Swift4からは明示的にかかないといけなくなったという感じかな。

とコメント頂きストンと落ち着きました。
ありがとうございました!
皆さまのご参考にもなれば幸いです!


​ <参考ページ>

dev.classmethod.jp

https://help.apple.com/xcode/mac/current/#/deve838b19a1?sub=devded6c2001

リリースアプリのアップデート

iOSアプリの開発を始めて2年半経ちました。そして5本のアプリをリリースすることができました。

始めた当初はとにかくリリースすることが精一杯。
それに反して溢れてくるアイデアとの折り合いをつけるのがとても大変でした。
なので出したら出しっぱなし。メンテナンスなんてしてませんでした。と言うかできませんでした。
新しいものを作りたい、けどコード書くのは遅い。そしたら出したもののケアは「取り敢えず後回し」になって。そして次第にそのことを忘れちゃって。

このようなループから最近抜け出しつつあります。
出したものについてある程度のケアをする (=アップデートをする) よう心がけています。

なぜ抜け出しせたのか? 順を追って説明していきましょう。

事実1 直近リリースした2つのアプリを気に入っている

一つ目としては、直近リリースした二つのアプリ、 ポーン - プロフェッショナルな名言をカウントしようぼかすん - 背景ぼかし & 消したい部分を簡単に隠せる への思い入れが強いことが関連しています。
かわいい子達の手入れを出来るだけしてあげたい。そんな思いが生まれます。

事実2 新規でアプリを起こすのに大変エネルギーがいるようになった

二つ目としては、先に述べた二つのアプリのお陰でリリースしようと思うハードルが自分の中で上がってしまったことが関連しています。
それまでは気にしていなかった部分についてもケアするようになり、アプリ一つを新規で起こすことが大変エネルギーのいる作業と感じるようになってしまっているのです。

事実3 新しいことは試したい

新規でアプリを起こすのは大変だけど、新しいアイデアや新しく覚えたことは試したいのです。

じゃあリリース済みのアプリをアップデートすることで新しいことを試せばいいんじゃない?

そう。新規でアプリで作るにはエネルギーはいるものの既存のアプリに新機能を追加するのであれば、新規で起こすのに比べれば全然負担は楽。
尚且つ、可愛いアプリ達がよりいいものになるので一石二鳥。

と言うわけで最近はそれ以前のものも含めて、楽な気持ちでアップデート出来るようになってきました! これは良いことだなぁと個人的には感じています。

ポーン - プロフェッショナルな名言をカウントしよう は名言メモ機能(以下の画像や動画の保存)の追加、ぼかすん - 背景ぼかし & 消したい部分を簡単に隠せる はぼかしエフェクト(モザイクとクリスタル)のリリース時に比べ追加しています。 もし良かったら試してみて下さい!

f:id:anthrgrnwrld:20170915183250j:plain f:id:anthrgrnwrld:20170915183352p:plain

swiftでの配列の初期化方法について

本日は配列の宣言についてメモ書きしておきます。 勘違いからミスってしまって解決するまでの流れを書いていきます。

以下みたいな感じでfor文で配列imageArrayにボコボコ値(UIImage型)を入れていきたい場合を考えます。

for i in 0 ..< numberOfPicture {  
    imageArray.append(UIImage(named:"\(i).png")!)  
}  

この場合、上記処理の前に配列imageArrayについて宣言をしておかなければなりません。
僕、初め以下のように宣言しちゃっていたんですね。

var imageArray: [UIImage] = [UIImage()]

この誤った宣言で処理を進めるとどうなるのか。

例えばpngファイルが1.pngから5.pngの5枚あった場合を考えましょう。つまりnumberOfPicture = 5の場合です。
期待する処理A後の要素数 imageArray.count は勿論5です。 しかしながら誤った宣言で処理Aを実行した後の imageArray.count は6になってしまうのです。 期待値としては1.pngはimageArray[0]に入っていてほしいし、5.pngはimageArray[4]に入っていて欲しいですが、1.pngはimageArray[1]、5.pngはimageArray[5]に入っています。

なぜ期待した値より1増えたメンバー数となるのか。

誤った宣言部をもう一度見てイコール以降の右辺部に注目して下さい。
[UIImage()]となっています。
この場合、配列の0番目には空っぽのUIImage型の何かが入ってしまうのです。
その配列に処理Aで書いたような形でappendを使用してメンバーを追加した場合はどうなるか?もうお分りと思います。
appendは既存の配列の最後にメンバーを追加するものなので、1.pngはimageArray[1]に追加されるし、5.pngはimageArray[5]に追加されてしまうのです。

解決策は?

誤った宣言部を以下のように直して下さい。

var imageArray: [UIImage] = []

これで期待通りの動作をするはずです。

思ったこと

実は空っぽの配列の宣言をする時、いつもどのように書こうか迷っていたんですよね。 今回スッキリできてよかったです。

新しいアプリをリリースしました!名前は「ぼかすん」です。

タイトルの通り、新しいアプリをリリースしました!
「ぼかすん」という名前の画像編集アプリでございます。

関西弁です。「ぼかすやつ」という意味になります。
指でなぞったところをぼかすことができます。

f:id:anthrgrnwrld:20170720231345p:plain

なぞってぼかすだけじゃなく、モードを変更することでタップによる円ぼかしも実行可能です。
またスライダーで調整することによりドローサイズも変更できます。
スライダー上部ボタン「サイズ」が有効時に反映されます。

f:id:anthrgrnwrld:20170720231557p:plain

ぼかし度の変更は「ぼかし」が有効時に反映されます。 実行済みすべての箇所に反映されます。

f:id:anthrgrnwrld:20170720232220p:plain

消しゴムモードでなぞった部分をぼかす前の状態に戻すことができます。 画面全体をぼかした後に強調したい部分にこの機能を使用することで、効果的な写真へ変化させることができます。

f:id:anthrgrnwrld:20170720232527p:plain

編集完了後にはカメラロールへの保存の他に、Twitter, Facebook, Instagram, 他のアプリへ直接シェアできます。
以下のリンクの時期にシェアの仕方を調べてました。

f:id:anthrgrnwrld:20170720232751j:plain

anthrgrnwrld.hatenablog.com

anthrgrnwrld.hatenablog.com

ちなみにBarの類の表示処理にはUIVisualEffectViewを使用しています。
このアプリのメニューのお洒落さを全力で感じるために
[設定→一般→アクセシビリティ→コントラストを上げる→透明度を下げる] をOFF設定にして使用頂きたいところですね。

anthrgrnwrld.hatenablog.com

anthrgrnwrld.hatenablog.com

このような感じのアプリですがいかかでしょうか??
制作期間は1年超…。
電車の中オンリーの開発とはいえ、時間をかけすぎました。
まぁしかしなかなか勉強になったのは事実でして、それは良かったなと感じております。

因みに公開開始から5日間でダウンロード数が200を超えております。
ヒットアプリなんかと比べると足元には及びませんが、なかなかいい手応えのダウンロード数と思っております。
すぐに新機能を追加したアップデートをして、この感じを途切れさせないようにしたいな〜と感じております。