SlideShare a Scribd company logo
1 of 18
Download to read offline
UIViewにまつわるあれこれ
株式会社BizReach
プロダクトマーケティング本部
山下大輔
自己紹介
・山下大輔(やました だいすけ)
・2015年1月よりビズリーチのiOSエンジニア
https://itunes.apple.com/jp/app/haikurasu-ren-cainokyaria/id972002786?mt=8
開発初期段階でよくある風景
デザイナ
エンジニア
プロトタイプ レイアウト指示書
デザイン反映
比較
配布
テスター
(チームメンバ)
フィードバック
ポテトチップスについて
レイアウト指示書 実際の実装(テスト配布アプリ)
比較
60 60
8
こういう状況で問題点をみつけないといけない
14pt #000000
8
ポテトチップスはしお味よりものりしお味
を選ぶ傾向にあります。コンソメ味も捨て
がたいですがのりしお味が食べたい。
ポテトチップスについて
ポテトチップスはしお味よりものりしお味
を選ぶ傾向にあります。コンソメ味も捨て
がたいですがのりしお味が食べたい。
13pt #0000008
背景 #FFFFFF
位置がズレてる?サイズ合ってる?フォント合ってる?
課題
デザイナさんが作成したレイアウト指示書を参考に
目視で確認
->テスターのセンスに依存
->微妙なレイアウト崩れを発見しにくい
->色の違いなどあっているか不安
->フィードバックの質の低下
テスト配布したアプリからでも
各View要素の詳細が確認できるようにしたい
という野望
・Debug view Hierarchy from Xcode 6
view構造っぽいやつがでる
viewの位置情報
Xcodeを使う
コード上から
view.recursiveDescription()
objective-cのprivate method(recursiveDescription)を叩く
ログを表示させる
コード上から
view.recursiveDescription()
objective-cのprivate method(recursiveDescription)を叩く
ログを表示させる
<UILayoutContainerView: 0x7f8cf0d6a720; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x7f8cf0d41da0>>
¦ <UITransitionView: 0x7f8cf0d6bff0; frame = (0 0; 375 667); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x7f8cf0d2a780>>
¦ ¦ <UIViewControllerWrapperView: 0x7f8cf0d6f6e0; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x7f8cf0d6c550>>
¦ ¦ ¦ <UIView: 0x7f8cf0d70060; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x7f8cf0d6f100>>
¦ ¦ ¦ ¦ <UIImageView: 0x7f8cf0d703b0; frame = (16 20; 290 200); autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x7f8cf0d6f0b0>>
¦ ¦ ¦ ¦ <UIButton: 0x7f8cf0d70e50; frame = (21 228; 46 30); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x7f8cf0d6f6c0>>
¦ ¦ ¦ ¦ ¦ <UIButtonLabel: 0x7f8cf0f70160; frame = (0 6; 46 18); text = 'Button'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7f8cf0f70320>>
¦ ¦ ¦ ¦ <UIButton: 0x7f8cf0d72020; frame = (21 266; 324 113); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x7f8cf0d72240>>
¦ ¦ ¦ ¦ ¦ <UIButtonLabel: 0x7f8cf0f6e750; frame = (139 47.5; 46 18); text = 'Button'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7f8cf0f6e910>>
¦ ¦ ¦ ¦ <UIButton: 0x7f8cf0d70170; frame = (21 258; 46 30); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x7f8cf0d70390>>
¦ ¦ ¦ ¦ ¦ <UIButtonLabel: 0x7f8cf0f6bed0; frame = (0 6; 46 18); text = 'Button'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7f8cf0f6c210>>
¦ ¦ ¦ ¦ <UIView: 0x7f8cf0d6a980; frame = (314 20; 51 143); autoresize = RM+BM; layer = <CALayer: 0x7f8cf0d70a90>>
¦ ¦ ¦ ¦ <_UILayoutGuide: 0x7f8cf0d64380; frame = (0 0; 0 20); hidden = YES; layer = <CALayer: 0x7f8cf0d64530>>
¦ ¦ ¦ ¦ <_UILayoutGuide: 0x7f8cf0d71070; frame = (0 618; 0 49); hidden = YES; layer = <CALayer: 0x7f8cf0d6c570>>
¦ <UITabBar: 0x7f8cf0c35b10; frame = (0 618; 375 49); autoresize = W+TM; layer = <CALayer: 0x7f8cf0c31ae0>>
¦ ¦ <_UITabBarBackgroundView: 0x7f8cf0f77590; frame = (0 0; 375 49); autoresize = W; userInteractionEnabled = NO; layer = <CALayer: 0x7f8cf0f77910>>
¦ ¦ ¦ <_UIBackdropView: 0x7f8cf0f77d90; frame = (0 0; 375 49); opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = <_UIBackdropViewLayer:
0x7f8cf0d74a60>>
¦ ¦ ¦ ¦ <_UIBackdropEffectView: 0x7f8cf0d75c50; frame = (0 0; 375 49); clipsToBounds = YES; opaque = NO; autoresize = W+H; userInteractionEnabled = NO; animations =
{ filters.colorMatrix.inputColorMatrix=<CABasicAnimation: 0x7f8cf0c02ed0>; }; layer = <CABackdropLayer: 0x7f8cf0d76390>>
¦ ¦ ¦ ¦ <UIView: 0x7f8cf0d77200; frame = (0 0; 375 49); hidden = YES; opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x7f8cf0d77310>>
¦ ¦ <UITabBarButton: 0x7f8cf0f48890; frame = (2 1; 184 48); opaque = NO; layer = <CALayer: 0x7f8cf0f579a0>>
¦ ¦ ¦ <UITabBarButtonLabel: 0x7f8cf0f4cc70; frame = (77 35; 29.5 12); text = 'Item 1'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7f8cf0f47ef0>>
¦ ¦ <UITabBarButton: 0x7f8cf0d620d0; frame = (190 1; 183 48); opaque = NO; layer = <CALayer: 0x7f8cf0d61e50>>
¦ ¦ ¦ <UITabBarButtonLabel: 0x7f8cf0d623c0; frame = (76.5 35; 29.5 12); text = 'Item 2'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7f8cf0d57560>>
¦ ¦ <UIImageView: 0x7f8cf0d788d0; frame = (0 -0.5; 375 0.5); autoresize = W; userInteractionEnabled = NO; layer = <CALayer: 0x7f8cf0d78380>>
ライブラリとして作ってみる
方針
let window = UIApplication.sharedApplication().keyWindow
rootView = window?.rootViewController?.view
・表示中のアプリのrootViewを取得
・取得したviewから再帰的に子viewを取得していく
let childViews = view.subviews
・viewが取得できればあとは表示するだけ!
DEMO
view表示時に
スイッチを追加
観測できるview
にマーカーが付く
ポチポチすると
viewの詳細が観れる!!
func application(application: UIApplication, didFinishLaunchingWithOptions
launchOptions: [NSObject: AnyObject]?) -> Bool {
ViewMonitor.start()
return true
}
使い方
まとめ
・できるようになったこと
感覚による確認 数値による確認
おわりに
・以下で公開してますので気軽にご意見お願いします。スターほしい
ViewMonitor
https://github.com/daisuke0131/ViewMonitor
・勉強会主催してたりするのでご興味あったらご参加ください
http://d-cube.connpass.com/
daisuke0131

More Related Content

Viewers also liked

SQLiteDatabaseを無理矢理覗く
SQLiteDatabaseを無理矢理覗くSQLiteDatabaseを無理矢理覗く
SQLiteDatabaseを無理矢理覗くTakao Sumitomo
 
objc2swift (続・自動変換の野望)
objc2swift (続・自動変換の野望) objc2swift (続・自動変換の野望)
objc2swift (続・自動変換の野望) Taketo Sano
 
watchOS 2 新機能の細かい話
watchOS 2 新機能の細かい話watchOS 2 新機能の細かい話
watchOS 2 新機能の細かい話Shuichi Tsutsumi
 
AppStore申請を一式まるっと自動化する
AppStore申請を一式まるっと自動化するAppStore申請を一式まるっと自動化する
AppStore申請を一式まるっと自動化するTomoki Hasegawa
 
殺しても死なないアプリ 〜Core Bluetooth の「状態の保存と復元」機能〜
殺しても死なないアプリ 〜Core Bluetooth の「状態の保存と復元」機能〜殺しても死なないアプリ 〜Core Bluetooth の「状態の保存と復元」機能〜
殺しても死なないアプリ 〜Core Bluetooth の「状態の保存と復元」機能〜Shuichi Tsutsumi
 
意外と苦労する、一部の画面のみ ランドスケープ表示を許容する方法 (potatotips 第17回)
意外と苦労する、一部の画面のみ ランドスケープ表示を許容する方法 (potatotips 第17回)意外と苦労する、一部の画面のみ ランドスケープ表示を許容する方法 (potatotips 第17回)
意外と苦労する、一部の画面のみ ランドスケープ表示を許容する方法 (potatotips 第17回)将之 小野
 
Activity, Fragment, CustomView の使い分け - マッチョなActivityにさよならする方法 -
Activity, Fragment, CustomView の使い分け - マッチョなActivityにさよならする方法 -Activity, Fragment, CustomView の使い分け - マッチョなActivityにさよならする方法 -
Activity, Fragment, CustomView の使い分け - マッチョなActivityにさよならする方法 -Yuki Anzai
 
絶対落ちないアプリの作り方
絶対落ちないアプリの作り方絶対落ちないアプリの作り方
絶対落ちないアプリの作り方Fumihiko Shiroyama
 
Androidアプリ開発を楽にするために
Androidアプリ開発を楽にするためにAndroidアプリ開発を楽にするために
Androidアプリ開発を楽にするためにShuichi Takaya
 
山戸家の家庭内情報共有
山戸家の家庭内情報共有山戸家の家庭内情報共有
山戸家の家庭内情報共有Shigeki Yamato
 
既存プロジェクトにSwiftLintを導入した話
既存プロジェクトにSwiftLintを導入した話既存プロジェクトにSwiftLintを導入した話
既存プロジェクトにSwiftLintを導入した話akatsuki174
 
Google Maps を使ったアプリを作ってみた
Google Maps を使ったアプリを作ってみたGoogle Maps を使ったアプリを作ってみた
Google Maps を使ったアプリを作ってみたShigeki Yamato
 
KotlinつかってQiitaクライアント作った時の話
KotlinつかってQiitaクライアント作った時の話KotlinつかってQiitaクライアント作った時の話
KotlinつかってQiitaクライアント作った時の話shinnosuke kugimiya
 
3D touch for iOS
3D touch for iOS3D touch for iOS
3D touch for iOStoyship
 
Activity Transition Animation #potatotips 33
Activity Transition Animation #potatotips 33Activity Transition Animation #potatotips 33
Activity Transition Animation #potatotips 33bina1204 Hozuki
 
PUSH通知証明書作成ツールを作った
PUSH通知証明書作成ツールを作ったPUSH通知証明書作成ツールを作った
PUSH通知証明書作成ツールを作ったTomoki Hasegawa
 
TestFlightみたいなのを自作する
TestFlightみたいなのを自作するTestFlightみたいなのを自作する
TestFlightみたいなのを自作するTomoki Hasegawa
 

Viewers also liked (20)

SQLiteDatabaseを無理矢理覗く
SQLiteDatabaseを無理矢理覗くSQLiteDatabaseを無理矢理覗く
SQLiteDatabaseを無理矢理覗く
 
objc2swift (続・自動変換の野望)
objc2swift (続・自動変換の野望) objc2swift (続・自動変換の野望)
objc2swift (続・自動変換の野望)
 
watchOS 2 新機能の細かい話
watchOS 2 新機能の細かい話watchOS 2 新機能の細かい話
watchOS 2 新機能の細かい話
 
AppStore申請を一式まるっと自動化する
AppStore申請を一式まるっと自動化するAppStore申請を一式まるっと自動化する
AppStore申請を一式まるっと自動化する
 
殺しても死なないアプリ 〜Core Bluetooth の「状態の保存と復元」機能〜
殺しても死なないアプリ 〜Core Bluetooth の「状態の保存と復元」機能〜殺しても死なないアプリ 〜Core Bluetooth の「状態の保存と復元」機能〜
殺しても死なないアプリ 〜Core Bluetooth の「状態の保存と復元」機能〜
 
意外と苦労する、一部の画面のみ ランドスケープ表示を許容する方法 (potatotips 第17回)
意外と苦労する、一部の画面のみ ランドスケープ表示を許容する方法 (potatotips 第17回)意外と苦労する、一部の画面のみ ランドスケープ表示を許容する方法 (potatotips 第17回)
意外と苦労する、一部の画面のみ ランドスケープ表示を許容する方法 (potatotips 第17回)
 
Activity, Fragment, CustomView の使い分け - マッチョなActivityにさよならする方法 -
Activity, Fragment, CustomView の使い分け - マッチョなActivityにさよならする方法 -Activity, Fragment, CustomView の使い分け - マッチョなActivityにさよならする方法 -
Activity, Fragment, CustomView の使い分け - マッチョなActivityにさよならする方法 -
 
絶対落ちないアプリの作り方
絶対落ちないアプリの作り方絶対落ちないアプリの作り方
絶対落ちないアプリの作り方
 
Androidアプリ開発を楽にするために
Androidアプリ開発を楽にするためにAndroidアプリ開発を楽にするために
Androidアプリ開発を楽にするために
 
Em synchrony について
Em synchrony についてEm synchrony について
Em synchrony について
 
山戸家の家庭内情報共有
山戸家の家庭内情報共有山戸家の家庭内情報共有
山戸家の家庭内情報共有
 
既存プロジェクトにSwiftLintを導入した話
既存プロジェクトにSwiftLintを導入した話既存プロジェクトにSwiftLintを導入した話
既存プロジェクトにSwiftLintを導入した話
 
ゲンバのSwift
ゲンバのSwiftゲンバのSwift
ゲンバのSwift
 
Google Maps を使ったアプリを作ってみた
Google Maps を使ったアプリを作ってみたGoogle Maps を使ったアプリを作ってみた
Google Maps を使ったアプリを作ってみた
 
KotlinつかってQiitaクライアント作った時の話
KotlinつかってQiitaクライアント作った時の話KotlinつかってQiitaクライアント作った時の話
KotlinつかってQiitaクライアント作った時の話
 
3D touch for iOS
3D touch for iOS3D touch for iOS
3D touch for iOS
 
DeviceOwnerのお話
DeviceOwnerのお話DeviceOwnerのお話
DeviceOwnerのお話
 
Activity Transition Animation #potatotips 33
Activity Transition Animation #potatotips 33Activity Transition Animation #potatotips 33
Activity Transition Animation #potatotips 33
 
PUSH通知証明書作成ツールを作った
PUSH通知証明書作成ツールを作ったPUSH通知証明書作成ツールを作った
PUSH通知証明書作成ツールを作った
 
TestFlightみたいなのを自作する
TestFlightみたいなのを自作するTestFlightみたいなのを自作する
TestFlightみたいなのを自作する
 

More from Daisuke Yamashita

State management for ios development
State management for ios developmentState management for ios development
State management for ios developmentDaisuke Yamashita
 
Convert the notification feature to the notification microservice
Convert the notification feature to the notification microserviceConvert the notification feature to the notification microservice
Convert the notification feature to the notification microserviceDaisuke Yamashita
 
歯磨き.go Go言語の静的解析とコード生成勉強会
歯磨き.go Go言語の静的解析とコード生成勉強会歯磨き.go Go言語の静的解析とコード生成勉強会
歯磨き.go Go言語の静的解析とコード生成勉強会Daisuke Yamashita
 
ライブラリを作って5年たったので振り返る
ライブラリを作って5年たったので振り返るライブラリを作って5年たったので振り返る
ライブラリを作って5年たったので振り返るDaisuke Yamashita
 
Introduction of ios-chart in oss-labs#3
Introduction of ios-chart in oss-labs#3Introduction of ios-chart in oss-labs#3
Introduction of ios-chart in oss-labs#3Daisuke Yamashita
 
About SnapKit - Open source lab -
About SnapKit - Open source lab -About SnapKit - Open source lab -
About SnapKit - Open source lab -Daisuke Yamashita
 
Swift open source library - ViewMonitor -
Swift open source library - ViewMonitor -Swift open source library - ViewMonitor -
Swift open source library - ViewMonitor -Daisuke Yamashita
 
Let's Start Swift Open Source Activity.
Let's Start Swift Open Source Activity.Let's Start Swift Open Source Activity.
Let's Start Swift Open Source Activity.Daisuke Yamashita
 
バグのことは嫌いになってもXcodeのことは嫌いにならないでください。
バグのことは嫌いになってもXcodeのことは嫌いにならないでください。バグのことは嫌いになってもXcodeのことは嫌いにならないでください。
バグのことは嫌いになってもXcodeのことは嫌いにならないでください。Daisuke Yamashita
 
Unity Introduction from 2D shooting game.
Unity Introduction from 2D shooting game.Unity Introduction from 2D shooting game.
Unity Introduction from 2D shooting game.Daisuke Yamashita
 
Introduction of Swift from Machine Learning
Introduction of Swift from Machine LearningIntroduction of Swift from Machine Learning
Introduction of Swift from Machine LearningDaisuke Yamashita
 
Introduction of Swift from Game Development
Introduction of Swift from Game DevelopmentIntroduction of Swift from Game Development
Introduction of Swift from Game DevelopmentDaisuke Yamashita
 

More from Daisuke Yamashita (18)

potatotips_77.pdf
potatotips_77.pdfpotatotips_77.pdf
potatotips_77.pdf
 
State management for ios development
State management for ios developmentState management for ios development
State management for ios development
 
Static analysis for go lang
Static analysis for go langStatic analysis for go lang
Static analysis for go lang
 
Convert the notification feature to the notification microservice
Convert the notification feature to the notification microserviceConvert the notification feature to the notification microservice
Convert the notification feature to the notification microservice
 
歯磨き.go #2
歯磨き.go #2歯磨き.go #2
歯磨き.go #2
 
歯磨き.go Go言語の静的解析とコード生成勉強会
歯磨き.go Go言語の静的解析とコード生成勉強会歯磨き.go Go言語の静的解析とコード生成勉強会
歯磨き.go Go言語の静的解析とコード生成勉強会
 
ライブラリを作って5年たったので振り返る
ライブラリを作って5年たったので振り返るライブラリを作って5年たったので振り返る
ライブラリを作って5年たったので振り返る
 
Tensorflow
TensorflowTensorflow
Tensorflow
 
Introduction of ios-chart in oss-labs#3
Introduction of ios-chart in oss-labs#3Introduction of ios-chart in oss-labs#3
Introduction of ios-chart in oss-labs#3
 
About SnapKit - Open source lab -
About SnapKit - Open source lab -About SnapKit - Open source lab -
About SnapKit - Open source lab -
 
View Monitoring Tips
View Monitoring TipsView Monitoring Tips
View Monitoring Tips
 
Swift open source library - ViewMonitor -
Swift open source library - ViewMonitor -Swift open source library - ViewMonitor -
Swift open source library - ViewMonitor -
 
Let's Start Swift Open Source Activity.
Let's Start Swift Open Source Activity.Let's Start Swift Open Source Activity.
Let's Start Swift Open Source Activity.
 
バグのことは嫌いになってもXcodeのことは嫌いにならないでください。
バグのことは嫌いになってもXcodeのことは嫌いにならないでください。バグのことは嫌いになってもXcodeのことは嫌いにならないでください。
バグのことは嫌いになってもXcodeのことは嫌いにならないでください。
 
Unity Introduction from 2D shooting game.
Unity Introduction from 2D shooting game.Unity Introduction from 2D shooting game.
Unity Introduction from 2D shooting game.
 
OpenCV on mobile
OpenCV on mobileOpenCV on mobile
OpenCV on mobile
 
Introduction of Swift from Machine Learning
Introduction of Swift from Machine LearningIntroduction of Swift from Machine Learning
Introduction of Swift from Machine Learning
 
Introduction of Swift from Game Development
Introduction of Swift from Game DevelopmentIntroduction of Swift from Game Development
Introduction of Swift from Game Development
 

How to measure UIView position on Native App