UIButtonが青色一色のベタで表示された時の対処
初歩的ミス
IBOutletで紐づけていたUIButtonにコードでimageをセットしてあげるも、青色一色でベタ塗りされた表示になっていた。
理由としては、UIButtonのTypeがSystem
だったために画像をセットしても青色で表示されていた。
Custom
に変えて正常に表示されたので、解決。
URLComponentsは、`+`をPercent Encodingしてくれない
経緯
APIを叩く際にランダムに生成しな内容をBASE64化してQueryにつけて送信しようとしていたが、5割ぐらいのエラーになっていた。
調査した結果、+
がPercent Encodingされていないためだったが、なぜこんなことが起きたのか…。
便利なURLComponentsの罠
この記事でURLComponents
という便利なものがある!自前でPercent EncodingしてQuery作らなくていいんだ!とうっきうきで使っていたわけだが、+
はPercent Encodingしてくれない。(ちなみに+
をPercent Encodingすると%2B
になる)
なぜ起こったか
今回のようなことが何故起こったのか。
URLComponents
は、説明にRFC 3986
に準拠していると記載されている。サーバ側がRFC 3986
に準拠していない作りが理由とも言えるし、自分がそこを確認怠り、URLComponents
を使用したのが理由とも言える。
URLComponents - Foundation | Apple Developer Documentation
サーバの作り次第で、このあたりはいくらでも変わるので、気をつけたいところ。
今回は、時間やコードの手戻りが厳しいこともありURLComponents
でQueryを付けた後、+
を%2B
に置換する力技で解決した。
URLComponents
に頼らない自作URLComponentsのようなものを作ってもいいかもしれないと思った。
WebView実装してリロードしまくったら出るNSURLErrorDomain エラー -999
前説
業務が忙しかったこともあり、色々ネタはありつつも書いてなかったので、落ち着いてきた今日あたりから徐々にまた書いていく。軽めにね。
NSURLErrorDomain エラー -999
WKWebViewを実装して特に制御せず、back
, forward
, reload
ボタンと処理を紐づけていたがため、reload
連打したらエラーなんか出たというバグ報告が上がった。
エラー内容は、
操作を完了できませんでした。(NSURLErrorDomain エラー -999。)
特にパッとなんでこのエラーが出たのか説明できなかったので、改めて調べた。
これは、発行したリクエストをキャンセルした際に返るエラーとのことで、reload
連打によりリクエストがキャンセルされてエラーとして返ってきてるために出ているものと判明。
ちなみにerror codeは、NSURLErrorCanceled
として定義されている。
NSURLErrorCancelled - Foundation | Apple Developer Documentation
UIBarButtonItemで画像の見たを変えずに使用するやり方
UIBarButtonItem
UIBarButtonItemは、UINavigationControllerとかと併せてよく使うButtonですが、そのまま使用すると下記のように透過じゃない部分は単色でTint Color
によって塗りつぶされます。
この画像を使用すると…
こうなる
これを画像を加工せずそのまま表示したいと思ったので、いいやり方ないか調べた際のメモです。
init(customView:)を使う
UIBarButtonIteminit(customView:)
という初期化方法にUIButtonを設定することで簡単に実現できる。
流れとしては、
- Storyboardで、UIButtonを用意する
- IBOutletで紐づける
- そのButtonを使用してコードでUIBarButtonItemを作成する
- UIBarButtonItemをセットする
そうすると、このようになる、
このやり方のメリットとして、StoryboardのUIButtonからIBActionを設定できるのでaddTarget
とかを使って#selector
で押下時の挙動を設定してあげる必要がない。
Storyboardを使わない場合
この場合、コードでUIButtonを生成して同じようにUIBarButtonIteminit(customView:)
でセットしてあげればよい。
AutoLayoutでmarginを画面比率によって変更したい時の対処
経緯
ふと前にも調べた気がするが、覚えていないなら覚えるまで同じ記事であろうか書くしかない。
AutoLayoutで制約をつけていると、固定のものは問題ないが、画面サイズによって可変にしたい場合、Viewのwidth
やheight
であれば、superviewとequal widthやequal heightしてから、割合で入力してやれば簡単にできるので困らない。
一方で、safeAreaのtopからのmarginとなると素直にやる方法がなくて困る。
UINavigationBarがないStoryboardなら使える方法
ものによっては、Vertically in Container
をつけて調整することで対応できるものもある。(具体的に言えば、UINavigationBarの影響がないStoryboard、LaunchScreen等)
ただ、これも万能ではなく、Storyboard上で上手く作れた様に見えて、実機で確認するとstatusBarやNavigationBarの高さが余分に含まれた見た目になることがある。
Storyboardを捨てるかどうか
marginを画面サイズから割合で出す方法は2つある。
1. Storyboardを使わない場合
UILayoutGuide
というものがあるので、これを使いましょう。
詳しくはこちら
Goodbye Spacer Views Hello Layout Guides
2. Storyboardを使う場合
これは、もう色々諦めの境地で空のUIViewをSpacerとして配置しましょう。
ViewとView、safeAreaとViewの間に置き、TopやBottom等を0marginでくっつけ、SpacerのViewのwidth
やheight
をsuperviewとの割合で調整します。調整が終わったら、hidden
にチェックをつけ、画面から見えないようにします。
これは意味もなくViewを置く無駄加減にモヤっとしますが、他に方法がないです。
UILayoutGuide
がInterface Builderに対応してくれれば、可能ですが、Xcode9の時点では無理です。(Xcode7時代からずっと今まで無理)