2017年8月20日日曜日

UITextViewのセンタリング

やりたいこと

ImageViewで描かれた吹き出しの中にTextViewを貼っている。
吹き出しの大きさが変更された時、中のテキストをそれに合わせ、吹き出しのできるだけ中心部分にセンタリングしたい。

必要なこと

TextViewのframeでなく、中のテキストが実際に表示されてる部分のrectを求め、それを元にセンタリングする。
CSSとかのpaddingに当たる値ですな。

TextViewの中のテキストの画面に表示されてる部分のみのrectはNSStringの以下の関数で得られる。
当然得られる値はTextViewのframe.sizeよりも小さくなる。

コード中のfdってのは俺のコードの都合なので無視して。
要は調べたいtextViewがどういうrectで、中のテキストはどんなフォント(サイズも含む)で画面に描画されるかを渡して調べてもらうわけだろう。

let rect = NSString(string: (fd!.textView.text)!)
                .boundingRect(with: (fd?.textView.frame.size)!,
                options: NSStringDrawingOptions.usesLineFragmentOrigin,
                attributes: [NSFontAttributeName : fd?.textView.font! as Any], context: nil)


textViewのframeサイズから得られたrectの値を引いて2で割れば上下/左右の均等なpaddingの値が求まる。
それをtextView.textContainerInset.〜に入れてやればいい。
textView.contentInset.〜と書かれてるサイトもあるけど、textContainerInsetじゃないとうまくいかないので注意。
contentInsetとはUITextViewの中にあるUIScrollViewに対するInsetだそうである。

var topPadding = (fd!.textView.bounds.size.height - rect.height * fd!.textView.zoomScale) / 2
topPadding = topPadding < 0.0 ? 0.0 : topPadding
var leftPadding = (fd!.textView.bounds.size.width - rect.width * fd!.textView.zoomScale) / 2
leftPadding = leftPadding < 0.0 ? 0.0 : leftPadding
//containerInset.topleft(上と左の余白)を設定
fd!.textView.textContainerInset.top = topPadding
fd!.textView.textContainerInset.bottom = topPadding / 2
fd!.textView.textContainerInset.left = leftPadding
fd!.textView.textContainerInset.right = leftPadding / 2

本来ならtopとbottom、leftとrightは同じ値を入れるべきだが、なんか微妙にテキストの位置が偏るみたいだったので、bottomとrightは値を半分にしたり、いろいろ変えてテストしてる。最適な値を探してみてほしい。
いいんだよ、理論がどうであろうと、見た目ちゃんとしてればw
また、描画の関係で文字が書かれるまでの空白とか少しできるけど、いいの。完璧じゃなくても。

参考サイト

2017年8月9日水曜日

変なメッセージ/dyld: Library not loaded:

昨日、Macの不調からかキーチェンアクセス中のiOS Develop証明書が消えてしまったらしく、頑張って再作成した。

その後、ちゃんと動作することを確認したプロジェクトが、今日になって以下のメッセージを出して落ちるようになった。

dyld: Library not loaded: @rpath/libswiftAVFoundation.dylib

ほんとはもっと長く続いてるんだけど、要するにライブラリがロードできないらしい。
ネットで調べてプロジェクトの設定をいじってみたけど直らない。一つだけじゃなく、他のいくつかのプロジェクトが同じ状態。

結局、プロジェクトをCleanしたらどうかという情報があったのでしてみたら、あっさり直ってくれた。

昨日証明書が消えた状態で起動して状態を見ていたプロジェクトだったから、そのせいだろうか。証明書再発行後にはちゃんと動くことを確認したんだけどな。
解せねえ…。

2017年8月2日水曜日

ARkitのクラス

iOS11から搭載されるARkitのクラスの情報の概要。
まあよくわからんのだけれども…。

拡張現実感(Augmented reality:AR)は、デバイスのカメラからのライブビューに2Dまたは3D要素を追加して、それらの要素を現実の世界に生息するように見せるユーザーエクスペリエンスを記述します。
ARKitは、デバイスのモーショントラッキング、カメラシーンキャプチャ、高度なシーン処理、および便利さの表示を組み合わせて、ARエクスペリエンスを構築する作業を簡素化します。

重要

ARKitには、A9以降のプロセッサを搭載したiOSデバイスが必要です。
あなたのアプリをARKitをサポートするデバイスでのみ利用できるようにするには、アプリのInfo.plistのUIRequiredDeviceCapabilitiesセクションにあるarkitキーを使用します。
拡張現実感がアプリの副機能である場合は、isSupported プロパティを使い、現在のデバイスが使用するセッション構成をサポートしているかどうかを判断します。

最初のステップ

ARSession class

拡張現実体験に必要なデバイスカメラとモーション処理を管理する共有オブジェクト。

構成(Configurations)

class ARSessionConfiguration

デバイスの向きのみを追跡する基本構成。
——デバイスの傾き(回転)に関してのみで、位置に関しての情報(デバイスを左に動かしたとかそういうこと)は扱わない。

class ARWorldTrackingSessionConfiguration

デバイスの向きと位置を追跡し、デバイスカメラが認識する実際の表面を検出する構成。
——デバイスの傾き(回転)と位置に関しての情報(デバイスを左に動かしたとかそういうこと)の双方を扱う。

標準ビュー(Standard Views)

Building a Basic AR Experience

ARセッションを設定し、SceneKitまたはSpriteKitを使用してARコンテンツを表示します。

class ARSCNView

3D SceneKitコンテンツを使用して、カメラビューを拡大するARエクスペリエンスを表示するためのビュー。

class ARSKView

2D SpriteKitコンテンツを使用して、カメラビューを拡大するARエクスペリエンスを表示するビュー。

カスタムビュー(Custom View)

Displaying an AR Experience with Metal

カメラ画像のレンダリングと位置追跡情報を使用して、オーバーレイコンテンツを表示することにより、カスタムARビューを構築します。

実世界の物体と位置(Real-World Objects and Positions)

class ARAnchor

ARシーンにオブジェクトを配置するために使用できる、実際の位置と方向。

class ARPlaneAnchor

ARセッションで検出された、実際の平面の位置と向きに関する情報。

class ARHitTestResult

ARセッションのデバイスカメラビュー内のポイントを調べることで見つかった、実際のサーフェスに関する情報。

カメラとシーンの詳細(Camera and Scene Details)

class ARFrame

ARセッションの一部としてキャプチャされた、ビデオ画像および位置追跡情報。

class ARCamera

ARセッションにおけるキャプチャされた、ビデオフレームのカメラ位置および撮像特性に関する情報。

class ARLightEstimate

ARセッション内のキャプチャされた、ビデオフレームに関連する推定シーン照明情報。