ラベル coding の投稿を表示しています。 すべての投稿を表示
ラベル coding の投稿を表示しています。 すべての投稿を表示

2017年10月26日木曜日

ハマったことシリーズ No19

今回も、開発の細かな話です。ハマったシリーズNo18では、UILabelに影付き文字列を設定していてハマった話をしましたが、今度はフォントによってUILabelが欠ける(特に、斜体系の場合)という現象に出くわした話です。

影付き文字列なので前後にスペース文字列を足して影の領域を確保していました。
左揃えの場合は、ちゃんと影もクロッピングされず綺麗に表示されています。 しかし、右揃えの場合は、文字が途中でクロッピングされてしまいます。スペース文字の個数などを増やしても表示に変化がありません。
なぜだ?? ということで、Debug view Hierarchyで見てみると、右揃えの場合、末端のスペース文字(全角・半角とも)が無視されるようです。(怒!! w)

Google先生に伺っても聞き方が悪いのかお答えが聞けず 散々悩んだ末、透明の文字列を末尾に追加することにしました。


let shadow = NSShadow()
shadow.shadowColor = .black
shadow.shadowBlurRadius = offset
let aStr = NSMutableAttributedStrings(string:"text")
aStr.addAttributes([NSShadowAttributeName:shadow], range: NSMakeRange(0, aStr.length))

let rStr = NSAttributedStrings(string:"-")
rStr.addAttributes([NSForegrounddColorAttributeName:UIColor.clear], range: NSMakeRange(0, rStr.length))
aStr.append(rStr)


という感じ。無事、期待通りの表示となりました! 先頭のスペース文字は無視しないが、末尾は無視するとは。。。 いや~、ハマった。


2017年6月29日木曜日

ハマったことシリーズ No18.

今回も、開発の細かな話です。アトリビュート付の文字列の描画がとても遅いという現象に出くわしました
やろうとしていた状況としては、40個位のUILabelがあって、それらに影つき文字列を設定しました。 その文字列の生成は、


let shadow = NSShadow()
shadow.shadowColor = .black
shadow.shadowBlurRadius = offset
let aStr = NSMutableAttributedStrings(string:"text")
aStr.addAttributes([NSShadowAttributeName:shadow], range: NSMakeRange(0, aStr.length))

という感じで作っていましたが、表示がえらく遅い。。。 この表示が遅いという点に囚われてしまい、小さな文字だったので気づかなかったのですが、実は影も表示されていませんでした。

半ば表示が遅いことを諦め、しばらく後に気が付いた影が表示されていないことに着目して調べていくと、offsetに想定の10倍の値を入れていました。つまり影の長さが長すぎる場合、描画が遅い現象になることが分かりました。ほとんど視認できないくらい薄い影を、真面目に画像計算をしていたという事なのでしょう。

プロファイラ―で調べたりイロイロしても、なかなか気づけませんでした。 いくら道具が優秀でも、視点がそこにないと分からないという典型でしょうか。 ハマりました。

2017年3月16日木曜日

ハマったことシリーズ No17.

今回は、Swiftでの開発で文字コードを文字に変換するという細かい話です。

文字コードから文字へ変換する場合、 "\u{2665}"という記述で文字コードを指定します。
これは知っていたのですが、はじめて実際に使いました。 そこでドハマリしました。
なぜか、思った文字が出ない。

原因は…
\u{nnnn}は 0xとかつけなければ10進数かと思っていたのです。 強制的に16進数だったとは!

いや~ お恥ずかしいw



2016年9月7日水曜日

ハマったことシリーズ No16.

今回は、Stroryboardで UIScrollViewを貼ったときに 不要な余白が入っちゃったお話です。

ヘルプ的なものを縦に長い画像で作り、それを縦スクロールで見てもらうことにしました。 このくらいはコード不要で出来るかなと調べると、とても参考になる記事が! ありがたや。
 [iOS] Storyboard上で UIScrollViewを設定する

基本的には このとおりやれば出来ます。 少し悩んだのが、UIImageViewの"高さ"の制約。 画像は事前に用意したものですが、参考記事のように高さの制約を絶対値で入れると、画像のアスペクト比が狂ってしまいます。UIImageViewにAspectFillを設定してもAutolayoutの計算には使ってくれないようで、UIImageViewのAspect比の制約を自分でちゃんと設定する必要があります。

これで出来上がりと思ったら、上部に不思議な余白が。。。  UIScrollViewの地色が見えていました。
UIScrollViewの上部制約をいつもの調子で Top Layout Guideに合わせたのが原因でした。 ただ、storyboard画面では綺麗にレイアウトされて見えるし、というか逆にSuperviewの上部に合わせると 下図のように 画像の上部が見えないし・・・、しばらく悩みました。

余白の高さは ナビゲーションバーの高さっぽいところでピンッと来て、試しにUIScrollViewの上部制約をSuperviewの上部に合わせてみると解決しました。

ナビバーがあるとUIViewControllerのルートに乗ってるUIViewが、縮み さらにTop Layout Guideの位置が、すなわち UIScrollViewの上部が下がるのでしょうかね?   っと言っても…、スクロールビューが下がり ルートViewが見えてるわけでもなく。。。。 ちょっと意味不明。  contentSizeとかがズレるのでしょうか。。。
ちょっと疑問点が残りますが、上手く行ったということでwww

2016年8月26日金曜日

ハマったことシリーズ No15.

今回は、swiftでiOSのバージョンが特定値以上かを判定するお話です。

以下のようなコードで iOS8系か、iOS9系かを判定していました。
ios8VersionFlag = Float(UIDevice.currentDevice().systemVersion) < 9

しかし、バージョンが 9.1などならいいのですが、9.3.4などとなると Float("9.3.4")というのはFloatに変換できず、nilとなる。 つまり、(nil < 9)の結果として、Flagがtrueとなってしまい、障害の原因となっていました。(see→補足)
最終的には、こんなコードにしました。 これなら安心。
ios8VersionFlag = UIDevice.currentDevice().systemVersion.compare("9.0.0", options:.NumericSearch ) == .OrderedAscending

2016年8月24日水曜日

ハマったことシリーズ No13.

今回は、UITextFieldのinputView に穴のあいたキーボードを設定しようとした話しです。


下のUIButtonが操作できるように、穴があいているキーボードをUIViewを継承して作ろうと思いました。 穴の部分は、そのUIView自体で、色をclearColorにして、タッチイベントをnextResponderに伝えようにしすればいいかなと。
穴でない部分は、普通のボタンなどを貼るつもりでした。

が、実際に作ってみると、ダメじゃん!! 

穴ない(ブラー??)、タッチイベントも通らない。 きっと、下地として UIViewがあるんですね。 


つまり、この方法はムリっぽいのね。 自力でやるしかないか。。。

ハマったことシリーズ No14.

今回は、複数Macでの開発に伴う試行錯誤の覚書です。

証明書のコピー




Organaizerで、「何度も キーチェーンのアクセスのID/PW入力がでる現象」


  • iOS Developer、Apple IDの秘密鍵のアクセス制御を、「これらのアプリ~常に許可」に ”xcode”を指定
  • iOS Distributionの秘密鍵は xcodeで常にではなく、全てのアプリに許可にする。(なぜ?w)
  • 証明書は 信頼 > 「システムデフォルトを使用」 にしておかないと、iTMS-90034エラーが出る。(上記現象を直す試行錯誤として、「常に信頼に」したらダメだった)


2015年2月19日木曜日

今回は、プログラミング関係で 先人達に学んだことを、つらつらと。


●写真編集系アプリでよくある 他のアプリとの連携はどうすればいいか?
UIDocumentInteractionControllerは、instagramと他のアプリとの両立方法が難しかった。参考になるのはこれ!

Stackoverflowの記事「UIDocumentInteractionControllerDelegate methods not called when open system apps like Mail, Messages, Twitter or Facebook
この記事で、 instagramには 「**.ig」ファイルを 他のアプリには 「**.png」ファイルを渡せるようになります。 質問者と回答者が同じなのが面白いw
Option付き(presentOptionsMenuFromBarButtonItem+ documentInteractionControllerWillPresentOptionsMenu)だと、なぜか うまくいかない…

Cocoaの日々の記事「UIDocumentInteractionController にファイルを別名で渡す」
ファイルが二ついるのだけど、二つセーブするのは非効率なので。ハードリンク使えばいいじゃん!という思いつきにつながった記事。 結局うまくいかなかったけどww

※Instagramアプリが 拡張子igだけでなく pngなどをサポートすればすむことなのだけど。。。w
※UIActivityViewControllerは、出てくるアプリの数が少ない。 LINEやInstagramを加えるにはカスタムを追加しなければならない。。。


●Flurry SDKを Swiftから使う
アプリの分析を無償で出来ることで有名なサービス。知らなかったけど、Yahooが買収したのですね。

Qiitaの「iOSでFlurry Analyticsを使ってみる」
makotton.com の「iOSにFlurry SDKを導入する」
この2つの記事は Objective-Cの場合ですが iOSで Flurryを使う手順が書いてあります。

AdMax Tech Blog の「【iOS】BridgingHeaderの使い方と設定方法」
この記事は、Objective-Cのライブラリを Swiftから使えるようにする手順が書いてあります。


●SpriteKitを使っているときの Pauseの話
バックグラウンドからの復帰時などに Pauseしない。。。 という障害を直すのに参考になった情報のリストです。

CODE NINJAの「Pausing a Sprite Kit Game, Correctly」
この記事がパーフェクト! ほかにも下記のような記事がありました。
http://stackoverflow.com/questions/19014012/sprite-kit-the-right-way-to-multitask


stackoverflowの「Difference between paused property of SKScene and SKView」
これは、タイトルのままですが pauseプロパティを持つものが2つあるので 何が違うの?という話。

shinyaohira / App States and Multitasking.mdの「アプリの状態とマルチタスキング」
アプリの状態遷移の話。 AppDelegateの各関数がどのタイミングで呼ばれるか?という話。





2015年1月21日水曜日

今回は、お勉強中のプログラミングの話。

レスポンシブとかアダプティブとかが流行ってるし(細かな違いは分かってないのですがw)、iOSのプログラミングもマルチ解像度時代ということで、ぼやっとしか理解できていなかったAutolayoutをお勉強しました。

かなり個人的なメモですが、いろいろ先人の情報を見て やっと腑に落ちたので公開します。

PinだとかAlignとかイロイロあるけど、分かりやすい解説はいっぱいあるし(例えばこれ)、バラバラには分かる。 分かるけど何か もやっ と引っかかっている。  理系なので、根底の原理原則のレベルで理解したい :-)
どの制約も制約編集画面(「Attributes Inspector」)を見ると 「First item」、「Relation」、「Second Item」、「Multiplier」、「Constant」が出てくる。 結局、どの制約も最終的に これらのパラメータで表せるっぽい。


FirstItem = multiplier × SecondItem + Constant

分かってみると簡単で、これらのパラメータは上式のような関係になっていて、等式だけではなく Relation ≦ ≧ という不等式も表せる。というものでした。 

Aspect Raitoも muliplierに1:2とか表示される。 これは 1/2 = 0.5 ということで、View.Width = 0.5 * View.Height つまり W:H=1:2となるわけですね。 簡単カンタン

で、Leadingは 左側のx座標で、Trailingは右側x座標だから、View.Leading = 0.5 * Superview.Trailing とかすると、親ビューと左右中央に 子ビューの左端が揃うわけですね。(multiple = 0.5 のときは View.Leading = Superview.centerXの方が直観的ですけどねw)。 で、20pixelマージンが欲しければ、View.Leading = 0.5 * Superview.Trailing + 20 とかすれば良いんだ。

最後に、size classと組み合わせた例が moving gifもあいまって、英語だけどわかりやすかったのでリンクを貼っておきます

もしかしたら続くかも… なので、その1ww 


2014年10月26日日曜日

こっそり、普段使いのシンプル電卓 malc(マルク)のバージョン: 1.21が公開になってます。 iPhone6/6Plusの画面解像度に最適化しました。


今日は、レビューへの誘導の話

ストアに★をつけてもらったり、コメントを書いてもらうレビューを書いてもらえたら、開発者として励みになるし、マーケティング効果も高いことは有名ですね。
有用なコメントをもらったり、好意的なレビューをしてもらうテクニックとして、レビューへの誘導タイミングや誘導方法が重要という情報もよく目にします。

いろいろ見てて、参考になる と思ったのは たとえば下記のようなWebページ
レーティング誘導で好評価を貰うには
アプリのレビュー評価はASOに効く!

「誘導は ある程度使ってもらってから」「ゲームならステージクリアしたときなど気分が良い時に」「好評価の工夫として”面白いので評価する/つまらないので評価しない”という誘導の文言にする」などがなるほど!と思いました。


私は、他のアプリを使っていても、起動直後にダイアログを出すものしか見たことがなく、とにかくウザイという認識でした。  そもそもmalcではAdも計算結果を表示した後に出すようにして、邪魔しないように気を付けているし、レイティング誘導は もっともっと 「とにかく邪魔しないように!」「余分なスペースを使いたくない! ということで、Adの領域に誘導バナーを出すことにしました。

iAdのようなデザインでレビュー依頼のバナーを相方に作ってもらい、2%の割合でレビュー依頼を出すようにしました。 これならモーダルダイアログではないのでユーザの作業に割り込みませんし、専用のスペースも取りません。また、何度も誘導されるのもウザイので、一度タップしてもらえれば二度と出ないようにしてあります。

そして、タップされたら、SKStoreProductViewControllerを使って AppStoreに誘導します。 ストリームで飛ばしてしまうとストアアプリに移動してしまいますが、この方法なら、アプリを出ないので元の画面にすぐに戻れ、わざわざ協力してくれた人に負担が少なくていいかと思います。

たくさん、★がつくといいなぁww

2014年10月13日月曜日

今回は まだ検討中のアプリの話

このアプリではいわゆる世界時計機能が必要なんです。
タイムゾーンが分かれば、日時を表示することは簡単。たとえば、America/Los_Angelesなら下記のようにすればできます。
    NSDate* date = [NSDate date] ;
    NSDateFormatter *formatter = [[NSDateFormatter alloc]init] ;
    [formatter setTimeZone:[NSTimeZone timeZoneWithName:@"America/Los_Angeles"]] ;
    [formatter setDateFormat:@"dd a HH:mm (zzz)"] ;
    NSLog(@"%@",[formatter stringFromDate:date]) ;

課題になるのは、国名・都市名からタイムゾーンを調べられる辞書が必要なのこと。
今回はそれについて調べました。

iOSが持っているタイムゾーンのリスト

主要都市のタイムゾーンはNSog(@"%@",[NSTimeZone knownTimeZoneNames]); で表示できます(iOS8で425タイムゾーンのデータが表示されました)
Africa/Abidjan
Africa/Accra
・・・
Pacific/Wallis
でもこれには、San Franciscoも載っていないレベル。 また、国名が分からないので、同名都市もあるし、国名から検索もできないので不便です。

tz database

このDBは、パブリックなタイムゾーンのデータデータベースで、America/Los_Angelesというような命名規則を作った おおもとデータなんですね。いろいろ工夫した末の命名規則のようです。いろんな所からD/Lできるようですが、ここから落としてみました(2014/9/24時点で415タイムゾーンのデータが格納されていました)
1,     AD,  Europe/Andorra
・・・
390, US,  America/Los_Angeles
・・・
415, ZW, Africa/Harare
zone.csvが上記のような国名の省略形とタイムゾーンの組の形式になっていて、国名の省略形と通常形の組のcountry.csvと合わせるとタイムゾーンの国名が分かります。knownTimeZoneNamesと比べて10都市くらい足りないけど、これくらいなら自力で調べられる範囲ですね。

City time zone

このDBは、千都市以上のタイムゾーンが載ってます(2014/10/3時点で1310都市のデータが格納されていました)。ただ、タイムゾーンが Tokyo Standard Timeなどの表記で iOSで使える形式ではないので、国名と都市名をもとに変換する必要があります。ただ、2つの都市が同じタイムゾーンだということが重要な情報で、Tokyo Standard TimeのOsakaのタイムゾーンが Asia/Tokyoに出来るわけです。

結合と変換

knownTimeZoneNamesと tzdataから、"国名/都市名"とタイムゾーン名のペアを作ります。
Ivory Coast/Abidjan, Africa/Abidjan
Ghana/Accra, Africa/Accra
・・・
Wallis and Futuna/Wallis, Pacific/Wallis
これを city time zoneと混ぜ(等価結合、VLookup)ます。 Japan/Tokyoが一致するので Tokyo Standard TimeをAsia/Tokyoに変換でき、同じタイムゾーンのOsakaも Asia/Tokyoと変換できます。 knownTimeZoneNamesにしかない都市や、city time zoneにしかないゾーンもあり、最終的には1478都市の辞書ができました。 そのうち、適当な場所で公開したいと思っております。

2014年9月17日水曜日



週末に「普段使いのシンプル電卓 malc」 のバージョンアップ申請をしました。 iOS8対応、iPhone6対応を含む多くの機能強化、新しいiTunesConnect と 盛りだくさんのアップデートです。 (申請しちゃったら、あとは すんなりレビューを通ってくれることを祈るしかありません)

さて、今回は、キーボードの進化について


きっかけはACキーとBSキーの切り替える機会が多くて面倒だったこと。これを何とかできないかを考え始めました。

最初の思いつきでは、
  • ACキーとBSキーを縦に並べ、その代わりにカーソルキーとして使うキーを1つに減らす 
  • カーソルキーを長押ししたら、すぐ上に、4つのカーソルキーすべてが表示される
という仕様でした。これならACキーとBSキーはとても使いやすくなります。
ただ、色を変える上下キーは滅多に使わないけど、左右キーは良く使うし同時に使う事が多いので、切り替えは面倒そう。 ということでボツにしました。

さきほどのアイディアを改良して、OS標準の日本語入力キーボードのように、フリック入力する方法で解決しようと思いました。
  • 長押しで、キーの上下左右に、隠れていた上下左右のカーソルキーが表示される
  • 表示前でもフリックで入力できる
という仕様です。 ただ、カーソルキーを左端や右端に置けなくなるのでボツ。

ここでいったん検討のキッカケまで戻って、なぜACキーとBSキーを切り替える機会が多いのかを考えました。 
まず答えを求めた直後に、ACを使うことが多いのは想定どおり(ここはACが表示されているのでOK)。 問題は、答えの数字を再利用しないのに、続けて数字をまちがって打ってしまった場合にACを使うこと、しかもその頻度が多いことだと気が付きました(その場合は、BSキー表示から ACキー表示に手動で切り替えないとダメ)。
自動的に答えが再利用されるより、計算結果を使う場合にはメモリをタップして、直前の答えを入力してもらう方が自然のような気がします。 そこで次のような仕様にしました。
  • 「答えの再利用をするか? しないか?の仕様を選んでもらう。デフォルトは「再利用しない」
  • 再利用されない時の答えを、式入力の時より明るい色の表示色にする
2つ目の仕様は、よく見ると答えが再利用されるかが見た目で区別できるようにという目的です。
プログラム的には、UITextViewのtext色よりplacehold色を明るくしておきます。そして再利用されない場合は答えは placeholdに代入します。これでキーを打つと答えが消えるというのが自然に実現できます。

これでおしまいにしてもよかったのですが、Cキーを付けたかったこともあり、キーボードはやはり進化させることに。ACやCキーは、他のキーに比べて誤って押しづらい方がいいということもあり、結局ACキーを独立させました。 場所は、キーボードの領域内ではなく、この記事のトップ写真のように、主表示(物理的な電卓でいうとLCDの部分ですね)領域の左上端にキーを置くことにしました。

さらにさらに、キー配置のカスタマイズができるようにしました。
大昔にCASIOが決めたという電卓型レイアウトは、下から0,1,2,3 ...と配置されます。 一方、 電話型(もう誰もそんな言い方しないプッシュフォンですねw)レイアウトは、上から 0,1,2,3 ...と配置されます。どちらが良いかは人により違うかもしれません。 テンキー以外も、デフォルトでは 演算子が左端 カーソルや=が右端ですが、逆に配置したり、両方とも右側に集めるというレイアウトも選べるようにしました。
具体的には 次のようなプログラミングにしています。
  • ボタンの生成と、配置を同時に行うのをやめ、分割して行う。
  • ボタンを生成(フォントサイズの調整、イベント登録)し、キートップの文字列をkeyとするNSDictionaryに ボタンオブジェクトを格納しておく。
  • 配置パターンは、キートップの配列を複数パターン作っておいて、設定でそれを選択する。
  • 全体レイアウトとテンキーレイアウトが入れ子関係なので、上記配列も入れ子関係で表現しておくき、その2つでボタンを配置を行う。


おまけと言ってはなんですが、キータッチを改善するために、BSとAC/CはUIControlEventTouchUpInside、それ以外はUIControlEventTouchDownでイベント処理するようにしました。 UIControlEventTouchDownにできるのは、ボタンが大きいデザインならではの修正です(ボタンが小さいとミスタッチが増えでかえって使いづらいと思います)。 この修正で、式の入力などはボタンを押したタイミングで反応するので、即応性が高まりました。修正系は押し間違えを防ぐため、わざと即応性を落としボタンを離したタイミングで反応するようにしています。
標準アプリも含めて他のアプリではあまりされていないようなとても細かい修整ですが、キモチ良く使っていただけると嬉しいです。



photo by 

2014年9月13日土曜日

今回は、UIWebViewがロードに失敗する現象についてです。

iOS8 で事前に遊べるXcoce 6 GM seedで、いままで動作していた以下のコードがfailする
[myWebView loadRequest:[NSURLRequest requestWithURL:url      cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:60]] ;

具体的には、iOS8環境では、1回目は上手く動いたあと、Xcodeで停止し 再度プログラムを起動すると
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error

が呼び出されてしまいます。(他のOSバージョンならちゃんと動く)
エラー内容は code:-1100 The requested URL was not found on this server.

そんなアホな、そのURLってローカルリソースなのだけど。。。 (キャッシュがあればキャッシュを使ってね! っていうポリシーに関係してるのかな)

あっ、そういえば 以前 そんな経験が!(経験は積んでおくものですねw)  前回は、キャッシュが動かなかっただけだったけど、また原因は、iOSシミュレータのバグ? ですかねぇ。
実機にiOS8を入れたら動いてくれるといいのだけど。


2014年5月24日土曜日

ハマったことシリーズ No12.

今回は、UIWebViewのキャッシュの話しです。

いままでUIImageなどで作っていた部品をクラウド上に置いておいて、自由に画像を差し替えられるようにしたい。 なので、UIWebViewのキャッシュを使う事を考えました。
いろいろググっていると、iOS5からUIWebViewのキャッシュはディスク上にも保存される という記事を見つけ、できることを確認し、コーディング。

[myWebView loadRequest:[NSURLRequest requestWithURL:url      cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:60]] ;

という感じにしておけば、オフラインでも画像表示でき、オンライン状態であれば 画像の差し替えもできるはず。 さぁテスト!

ここでハマリました。

そう、ぜんぜんキャッシュされない。 
原因は、iOSシミュレータのバグ?でした。 iOS6.1のシミュレータだけキャッシュされない。実機(6.1.3)ではしっかりキャッシュが動いてくれました。

最初はシミュレータで!というのも凝り固まらないようにしないとですね。

2014年5月21日水曜日

ハマったことシリーズ No11.

今回は、「UIViewControllerは、まず消える!?」です。  プログラマ以外の方には、意味不明のお話です。

自分の画面のためのクラスは、UIViewControllerを継承して作るお作法ですよね?
その元のUIViewControllerの標準メソッドの (void)viewWillDisappear:(Bool)animated のお話。

これ、画面が表示されるときに viewDidLoadの後に呼ばれることがあるのです。 ていうか自分で呼んでましたww。当然、通常は呼ばれないようですが、拾ってきたカスタムセグウェイの中で、一度rootViewControllerに設定して回転方向の修正をし、再度独自トランジッションをかけていたのです。

これでハマリました。

viewDidLoadで、addObserver: forKeyPath: options: context でオブザーバ追加し、
viewWillDisappearで、removeObserver: forKeyPath:でオブザーバ削除をしていたのですが、
待てど暮らせど、observerValueForKeyPath: ofObject: change: context: が呼ばれない。

そりゃそうです。 追加した直後に削除してりゃ、呼ばれるわけない。
設定してないときに removeObserverすると例外で落ちるので、フラグを使って設定してなければremoveObserverを呼ばないようにしていたので発見が遅れました。

原因が分かれば対処は簡単。viewDidAppearで addObserverするように変更し一見落着です。

2014年1月8日水曜日

カラバリ

 後付でカラーバリエーションをつけることにしました。つまり、キーボード、メモリーの部分の色をいろいろ変えられるようにしようと。 

 パーツがいっぱいあるので、それぞれ色を変えるのは結構面倒です。 しかも実は、一色というわけにはいきません。メモリーは視認性が悪くならないように縞々にしています。
 その面倒を解決する工夫としては、キーボードと メモリーのパーツは 非常に透明度が高い白や黒で着色しています。 つまり、それらを通して一番裏のUIViewが見えているわけです。 なので、このUIView1つだけの色を変えればよいわけです。 (実際には、入力中の計算式の表示エリアの文字色も変えてます)

 5cのカラバリに合わせ、malcは Apple Storeの第一画面もカラバリです。 アイコンもカラバリを意識したデザインです。  そんな一押しのカラバリですが、こんなとても簡単なシカケでできています。



2013年12月18日水曜日

コーディングスタート

 設計ができたので、そろそろコーディング開始です。
 まずは電卓なので、数式から答えを求める計算ロジックを作ります。 折角なのでw、ちゃんと優先順位つきのものが作りたい。1+3*3が先に足し算をして12になる電卓もあるけど、算数のルールどおりに掛け算を先に実行して10になってほしい。

 Rubyなら文字列で式を渡せば計算してくれたりしますが、どうやらそんな都合よいことはないので、自力で作ることになります。
 すぐに思いだしたのは、yacc, lex。大学の授業の課題で電卓作りました。 探せばソースもあるだろし、C言語なので使えると思うけど、コードが大きくなりそうな気がするのでボツに。
 次に思い出したのは、forthというか逆ポーランド計算(RPN)。懐かしいとか思いながら、これで作ることにしました。
通常の式からRPNに変換するために、2状態のオートマトンとスタック2つを使いました。 RPNになっちゃえば、計算は簡単。 演算子の計算に必要な個数の数字をスタックから取り出して計算するだけw。

といってもテストが煩雑なので、今回はじめてテストコードを書いてみました。 アタマでは分かっていてもやったことのないテストファースト。 なかなか面白いと思いましたが、この手のテストは教科書通りなので、簡単だったからかもしれません。 UIとか通信とか絡むと、難しいのかも。

2013年12月15日日曜日

今回は、iPadのプログラマーな方むけのとっても技術的なハナシです

iPadのUIPopoverを できるだけStoryboardを有効活用して作る場合のお話です。
(なお、Storyboardを使わないパターンは UIPopoverControllerチュートリアル その2 などが参考になりました。)


以下が最善の策かは分かりませんが、とりあえず動いているし、いろいろググって調べたものと比較しても簡単です。



■StoryboardでUIPopoverを設定する
SegueにIdをつけて、StyelはPopoverを選びます。これで接続されたUIViewController(destinationViewController)が Popoverで開きます。

でも、これだけだと

  • 自分自身の多重起動も含め、同時に二つ以上のPopoverが表示されます。
  • 閉じるボタンを作れない

という問題があります。


■Popoverを呼び出す UIViewControllerで解決する
呼び出し元のUIViewControllerに -(void)prepareForSegue: sender:を追加し、その中で

  1. staticなUIPopoverController変数を定義し、Popoverの二重起動を防ぐ
  2. Popoverで開かれるUIViewControllerにPopoverControllerを通知しておく
  3. 上記2つの処理はsegueがUIStoryboardPopoverSegueクラスの時に実施する

を行います。 あとは、呼び出されるUIViewControllerから PopoverControllerが参照されるので、 [self.popc dismissPopoverAnimated:YES] ; とすれば消すこともできます。


ソースも付けておきます。
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    static UIPopoverController* popoc = nil;
   
    if ([[segue identifier] isEqualToString:@"SplitViewFlip"]) {
        MasterViewController* mvc = [((UISplitViewController*)
                                 [segue destinationViewController]).viewControllers objectAtIndex:0] ;
        // mvc関連のデータ受け渡しをする
    }
    else if ([segue isKindOfClass:[UIStoryboardPopoverSegue class]]) {
        if ( popoc )
            [popoc dismissPopoverAnimated:NO] ;
        popoc = ((UIStoryboardPopoverSegue*)segue).popoverController ;
        if ( [segue.identifier isEqualToString:@"PlanPopover"]) {
            PlanViewController* pvc =(PlanViewController*)[segue destinationViewController] ;
            pvc.popc = popoc ;
        }
    }
}


2013年10月25日金曜日


先日、 iPhonePLUSにも載ってウキウキですw
今回は、crenieqの新アプリ誕生!malc(マルク)でもご紹介した「シンプル電卓 malc」の開発日記的なものを書きたいと思います。




はじまり


 なぜ電卓を作り始めようと思ったか。。。 なんでだっけ?w (オイ!)

 作りかけがいくつかあって、それぞれそれなりに進んでるけど未完成。 達成感を味わってモチベーションを維持したい! と考えて、簡単に完成しそうなネタとして選んだのがはじまりでしょうか。。。

 といっても、たとえ小さくても、新しいアイディアがなければ作る意味がない! 第一楽しく作れない!ということで、メモリー機能を簡単な概念にする方法を思いついたからかもしれません。

電卓によくあるメモリー機能。M+とかM-とか、分かりにくい機能という気がしませんか? エンジニア視点からすると 理解はできるですが、あらためて利用者視点で見ると「よく観るけど、何でこうなの?」という気がします。
 メモリー機能は、要は「値が再利用したい!」ということだと解釈しました。
だったら、履歴に残しておいてワンタップで再利用できるようにするのが自然な気がして、GUIをイメージしました。

 同じネタのものがあっては意味がないので、ストアに上がっている他の方の作品も調べてみました。  履歴が閲覧できるものもありました。 Kalc というアイコンに数字の5が入っているのが印象的なアプリや、アニメーションが美しいLluminoなどが見つかりました。 この2つには後々まで、かなり影響を受けたかもしれません。

両方とも素晴らしい!でも、自分がイメージしたものと少し違う。 
小さな違いですが、別画面で履歴閲覧できるタイプは他のアプリにもいろいろありましたが、沢山一覧できるというメリットはあるものの、一瞬ですが記憶に頼る点が気になりました。 普段、繰り返し使う電卓としては、「あれ?何計算しようと思ったんだっけか?」という一瞬にこだわりたいなと。 
Kalcは、同一画面で履歴閲覧できるけど、再利用がワンタップでできないコピペタイプでした。 これとも些細だけれど、差がある気がして、これを新しいアイディアということで作り始めました。

2012年10月13日土曜日


サポータルは、デザイナーさんが作ってくれた、とても綺麗なアイコンや背景、カスタムボタン、応援メッセージなどが一つのウリです。(連載している使い方解説を見てみて下さい。)

それらを沢山配置するのに、作ってもらったpngファイルのリソースファイルを使うわけですが、実機だけ表示できない という現象が起きました。
シミュレータではちゃんと表示されていたのに。。。。 転送ミスを疑い、cleanして再度ビルドしてもダメ。。。  というわけで、これもハマりました。

結論から言うと、「シミュレータはリソースファイル名の大文字小文字を区別しない」

実機はファイル名の大文字小文字を区別するのに、シミュレータはしない。 そこも、ちゃんとシミュレーションしてよー(笑) というわけで、コード上の参照ファイル名の記載ミスでした。