Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
No Story, No Board
Search
Elvis Shi
June 23, 2017
Programming
0
2.9k
No Story, No Board
Elvis Shi
June 23, 2017
Tweet
Share
More Decks by Elvis Shi
See All by Elvis Shi
SwiftUIで使いやすいToastの作り方 / How to build a Toast system which is easy to use in SwiftUI
lovee
3
150
SwiftUIで二重スクロール作ってみた / When I tried to make a dual-scroll-ish view in SwiftUI
lovee
1
190
Observation のあれこれ / A brief introduction about Observation
lovee
3
310
ChatGPT 時代の勉強 / Learning under ChatGPT era
lovee
22
6.6k
属人化しない為の勉強会作り / To make tech meetups with less personal dependencies
lovee
0
210
偏見と妄想で語るスクリプト言語としての Swift / Swift as a Scripting Language
lovee
2
650
danger-swift-kantoku
lovee
1
410
Decimal、正しく使ってる? / Are you using Decimal correctly?
lovee
4
580
A story about me trying to make a router that manages when, how and which view to transit in a SwiftUI app
lovee
1
330
Other Decks in Programming
See All in Programming
2 週間で Twitter Bot を作ってみた
contour_gara
0
490
Anthropic Cookbook のおすすめレシピ
schroneko
7
980
"config" ってなんだ? / What is "config"?
okashoi
0
240
GitHub Actionsで泣かないためにやっておきたい設定 / Recommended GHA settings to avoid crying
pinkumohikan
3
540
使ってみよう Azure AI Document Intelligence
kosmosebi
2
320
Build Apps for iOS, Android & Desktop in 100% Kotlin With Compose Multiplatform (mDevCamp 2024)
zsmb
0
340
はてなにおける CSS Modules、及び CSS Modules に足りないもの / CSS Modules in Hatena, and CSS Modules missing parts
mizdra
7
930
DMMプラットフォームがTiDB Cloudを採用した背景
pospome
8
4.1k
TCAとKMPを用いた新規動画配信アプリ 「ABEMA Live」の設計
tomu28
1
110
MetricKitで予期せぬ終了を検知する話 / Detect unexpected termination with MetricKit
nekowen
1
190
TYPO3 v13 – The road to LTS: What's new and new APIs
luisasofie_xoxo
0
200
コーンフレークから始める モデリング会話入門
ogurotakayuki
0
370
Featured
See All Featured
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
187
16k
The Straight Up "How To Draw Better" Workshop
denniskardys
227
130k
Why Our Code Smells
bkeepers
PRO
331
56k
Designing the Hi-DPI Web
ddemaree
276
33k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
7
1k
Optimising Largest Contentful Paint
csswizardry
8
2.4k
GraphQLとの向き合い方2022年版
quramy
32
12k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
121
39k
Six Lessons from altMBA
skipperchong
21
3k
RailsConf 2023
tenderlove
4
540
Design by the Numbers
sachag
274
18k
Being A Developer After 40
akosma
57
580k
Transcript
No Story No Board for iOS UI࣮ษڧձ
override init() { super.init() emplyedBy = "MAGES. 5pb. Game div"
job = "iOS Developer" twitter = "@lovee" qiita = "@lovee" github = "el-hoshino" additionalInfo = "ʮAuto Layout ઈରࡴ͢ϚϯʯͰ͢" class Speaker: Developer { } }
ࠓ·ͰͷาΈ
ࠓ·ͰͷาΈ ͓ɺͬͺΈΜͳ Storyboard ݏ͍Μ͚ !
ࠓ·ͰͷาΈ
ࠓ·ͰͷาΈ ٸͳొஃͰ͔ͨ͠Β४උෆͰશવΕͳ͔ͬͨ "
ࠓ·ͰͷาΈ
ࠓ·ͰͷาΈ HITMAN ʹϋϚͬͯͦͦ४උͰ͖ͳ͔ͬͨ "
ࡾͷਖ਼ʹͳΔͷ͔"
໔໌ ͜ͷൃද Storyboard Λ dis ΔൃදͰ͢ ͕ɺผʹօʹ͜ͷߟ͑Λԡ͚͍ͨ͠ͱࢥΘͳ͍ ͜ͷൃදϋʔυίʔσΟϯά࠷ߴͱݴ͍ͬͯͳ͍ Storyboard ϋʔυίʔσΟϯάͦΕͧΕͷ᠘͕͋Δ
ͦͦࢲ GUI Ͱ GUI Λ࡞Δ͜ͱࣗମʹେࢍ ͨͩ Storyboard ͷ࣮͕೦͗͢ΔͱࢥͬͯΔ͚ͩ
ࢲ͕ Storyboard ΛΘͳ͍ཧ༝ʢ1ʣ Auto Layout ͷ੍Λ͏ View ͕૿͑Δͱ੍͕രൃ తʹ૿͑Δ ʮ͜ͷ
View ͷ͜ͷ੍ʯ͕ ୳ͮ͠Β͍
ࢲ͕ Storyboard ΛΘͳ͍ཧ༝ʢ2ʣ Swift ͳͷʹ IUO Λ͏ UIViewController ͷϥΠϑ αΠΫϧΛѲ͠ͳ͍ͱ
མͪΔ͜ͱ͋Δ ؾ࣋ͪѱ͍
ৄ͘͠ http://qiita.com/lovee/items/acfc9d0f1ffa7207b38b Λ͝ཡ͍ͩ͘͞#
One more thing!
UIStackView Auto Layout LayoutKit Manual Layout PinLayout ※ग़యɿhttps://github.com/mirego/PinLayout/blob/master/docs/Benchmark.md 銙闗#WVQ.C[QWV闖㢚閴聮閳闋闇#
ͦΕͰ Auto Layout ͍͍ͨํ PureLayout macOS / iOS ྆ํͰར༻Ͱ ͖Δ
Swift / Objective-C ྆ํͰ ར༻Ͱ͖Δ AutoLayout ੍Λ؆ܿʹɺ ͔ͭൺֱతʹ͔Γ͢ ͘ॻ͚Δ ͔ͳΓॆ࣮͍ͯ͠Δࢿྉ
ͦΕͰ Auto Layout ͍͍ͨํ SnapKit macOS / iOS / tvOS
શ෦ར ༻Ͱ͖Δ Swift ͷߏจಛΛ࠷େݶ ʹҾ͖ग़͍ͯ͠Δ গ͘͠ͳΔ͕ɺඇৗʹ ͔Γ͍͢จ๏ ඇৗʹॆ࣮͍ͯ͠Δެࣜ ࢿྉ
–Elvis Shi lͬͺΓɺ"VUP-BZPVUΛΘͣʹ ίʔυͰ6*ΛΈ͍ͨz
㘦㖽㘼㗧㙟㘗㘕㘙㘻㘒ଡ଼㘀㘬㘬㙔 UIView / UIViewController ͷϥΠϑαΠΫϧΛཧղ͢Δ ରΛ࿔Δɺରʹৄ͘͠ͳΔඞཁ͕͋Δ ϨΠΞτΛઃఆ͢ΔϓϩύςΟʔΛཧղ͢Δ ؒҧͬͨϓϩύςΟʔͷॻ͖ࠐΈࢥΘ͵όάΛট͘ αʔυύʔςΟʔϥΠϒϥϦʔΛཧղ͢Δ ศརͳ໘ɺࢥͬͯΔͷͱಈ͖͕ҧ͏Մೳੑ͋Δ
UIView / UIViewController ͷϥΠϑαΠΫϧΛཧղ͢Δ UIViewController UIView loadView() viewDidLoad() viewWillAppear() viewWillLayoutSubviews()
layoutSubviews() viewDidLayoutSubviews() viewDidAppear() layout runloop viewWillDisappear() viewDidDisappear() layoutIfNeeded() Needs layout? sleep viewWillLayoutSubviews() layoutSubviews() viewDidLayoutSubviews() Disappear? no yes yes no Needs layout?
UIView / UIViewController ͷϥΠϑαΠΫϧΛཧղ͢Δ Ͳ͏ͬͯఆ͍ͯ͠Δͷ͔ʁ Needs layout? setNeedsLayout() Λݺͼग़ͨ͠ σόΠε͕ճసͨ͠
ࢠϏϡʔΛՃআΛͨ͠ ʢUIScrollView Ͱ͋ΔࢠϏϡʔʣ͕εΫϩʔϧͨ͠ ࣗͷࢠϏϡʔͷ frame transform ͳͲ͕มߋ͞Εͨ ͳͲͳͲ…
UIView / UIViewController ͷϥΠϑαΠΫϧΛཧղ͢Δ Ͳ͏ͬͯఆ͍ͯ͠Δͷ͔ʁ Needs layout? setNeedsLayout() Λݺͼग़ͨ͠ σόΠε͕ճసͨ͠
ࢠϏϡʔΛՃআΛͨ͠ ʢUIScrollView Ͱ͋ΔࢠϏϡʔʣ͕εΫϩʔϧͨ͠ ࣗͷࢠϏϡʔͷ frame transform ͳͲ͕มߋ͞Εͨ ͳͲͳͲ… ࣗͷ frame transform Λมߋ͢Ε ͷ layoutSubviews() ݺΕΔʂ ࣗͷ frame transform ඞͣʹมߋͯ͠Β͓͏ʂ
–Elvis Shi l6*7JFXͷGSBNFUSBOTGPSNɺ ࣗͷͰͳ͘ɺͷͷz
ϨΠΞτΛઃఆ͢ΔϓϩύςΟʔΛཧղ͢Δ view.frame = CGRect(x: 0, y: 0, width: 200, height:
200)
ϨΠΞτΛઃఆ͢ΔϓϩύςΟʔΛཧղ͢Δ view.frame = CGRect(x: 0, y: 0, width: 200, height:
200) view.transform = view.transform.rotated(by: .pi / 4)
ϨΠΞτΛઃఆ͢ΔϓϩύςΟʔΛཧղ͢Δ view.frame = CGRect(x: 0, y: 0, width: 200, height:
200) view.transform = view.transform.rotated(by: .pi / 4) view.frame.size.width = 100
ϨΠΞτΛઃఆ͢ΔϓϩύςΟʔΛཧղ͢Δ view.frame = CGRect(x: 0, y: 0, width: 200, height:
200) view.transform = view.transform.rotated(by: .pi / 4) view.frame.size.width = 100 Α͘ΒΜ͕ frame.size.width Λʹͨ͠Β ෯ߴཱͪ͞Ґஔશ͕ͯมΘͬͨ"
※ग़యɿhttps://developer.apple.com/documentation/uikit/uiview/1622621-frame
͠ transform ϓϩύςΟʔ͕ identity Ͱͳ͚Εɺ ͜ͷϓϩύςΟʔͷະఆٛͱͳΓɺ ແࢹ͖͢Ͱ͋Δɻ ʢҙ༁ɿ৮Δͳ΄ͬͱ͚ʂʣ ※ग़యɿhttps://developer.apple.com/documentation/uikit/uiview/1622621-frame
frame Λ࿔Γ͍ͨͳΒ ΘΓʹ center ͱ bounds.size ͷํΛ ࿔Εʂ ※ग़యɿhttps://developer.apple.com/documentation/uikit/uiview/1622621-frame
ϨΠΞτΛઃఆ͢ΔϓϩύςΟʔΛཧղ͢Δ view.bounds.size = CGSize(width: 100, height: 100) view.center = CGPoint(x:
base.bounds.midX, y: base.bounds.midY)
ϨΠΞτΛઃఆ͢ΔϓϩύςΟʔΛཧղ͢Δ view.bounds.size = CGSize(width: 100, height: 100) view.center = CGPoint(x:
base.bounds.midX, y: base.bounds.midY) view.layer.anchorPoint.y = 0
ϨΠΞτΛઃఆ͢ΔϓϩύςΟʔΛཧղ͢Δ view.bounds.size = CGSize(width: 100, height: 100) view.center = CGPoint(x:
base.bounds.midX, y: base.bounds.midY) view.layer.anchorPoint.y = 0 Α͘ΒΜ͕ layer.anchorPoint Λมߋͨ͠Β ࣗͷॴ͕มΘͬͨ"
※ग़యɿhttps://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreAnimation_guide/CoreAnimationBasics/ CoreAnimationBasics.html#//apple_ref/doc/uid/TP40004514-CH2-SW3
anchorPoint ͱϨΠϠʔͷ ϙδγϣχϯάͷؔʹ͍ͭͯ ʢҙ༁ɿcenter ͕ࢦͯ͠Δͷ anchorPoint ͷ ॴͳΜʂʣ ※ग़యɿhttps://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreAnimation_guide/CoreAnimationBasics/ CoreAnimationBasics.html#//apple_ref/doc/uid/TP40004514-CH2-SW3
–Elvis Shi lUSBOTGPSN͕ॳظ͡Όͳ͍Մೳੑ͕͋Εɺ GSBNFΛઃఆͤͣʹ CPVOETTJ[FͱDFOUFSΛઃఆ͠Α͏z
αʔυύʔςΟʔϥΠϒϥϦʔΛཧղ͢Δ
αʔυύʔςΟʔϥΠϒϥϦʔΛཧղ͢Δ ݟͨײ͡ͰͲ͏Β frame ʹॻ͖ࠐΜͰͦ͏$
αʔυύʔςΟʔϥΠϒϥϦʔΛཧղ͢Δ segmented.transform = segmented.transform.rotated(by: .pi/4)
αʔυύʔςΟʔϥΠϒϥϦʔΛཧղ͢Δ segmented.transform = segmented.transform.rotated(by: .pi/4) Γ transform Λ࿔ͬͨΒ ϨΠΞτͰόάͬͨ"
NotAutoLayout https://github.com/el-hoshino/NotAutoLayout
αʔυύʔςΟʔϥΠϒϥϦʔΛཧղ͢Δ segmented.transform = segmented.transform.rotated(by: .pi/4)
αʔυύʔςΟʔϥΠϒϥϦʔΛཧղ͢Δ segmented.transform = segmented.transform.rotated(by: .pi/4) bounds.size ͱ center Λઃఆ͍ͯ͠ΔͷͰɺ transform
Λมߋͯ͠ϨΠΞτ่Ε͠ͳ͍
let titleViewLayout = Layout .makeCustom(x: { _ in 0 },
y: { _ in 0 }, width: { $0.width }, height: { _ in 60 }) baseView.addSubview(titleView, constantLayout: titleViewLayout) NotAutoLayout 1.0
baseView.nal.setupSubview(titleView) { $0 .setDefaultLayout { $0 .pinTopCenter(to: baseView, s: .topCenter)
.setWidth(to: baseView, s: .width) .setHeight(to: 60) } .addToSelf() .commit() } NotAutoLayout 2.0ʢԾʣ
–Elvis Shi l/PU"VUP-BZPVUΛͥͻࢼͯ͠Έ͍ͯͩ͘͞ 'FFECBDLͱ4UBSΛ͓͓ͪͯ͠Γ·͢z