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
How did I build an Open-Source SwiftUI Toast Library
lovee
1
48
SwiftUIで使いやすいToastの作り方 / How to build a Toast system which is easy to use in SwiftUI
lovee
3
660
SwiftUIで二重スクロール作ってみた / When I tried to make a dual-scroll-ish view in SwiftUI
lovee
1
240
Observation のあれこれ / A brief introduction about Observation
lovee
3
330
ChatGPT 時代の勉強 / Learning under ChatGPT era
lovee
26
8.2k
属人化しない為の勉強会作り / To make tech meetups with less personal dependencies
lovee
0
270
偏見と妄想で語るスクリプト言語としての Swift / Swift as a Scripting Language
lovee
2
790
danger-swift-kantoku
lovee
1
490
Decimal、正しく使ってる? / Are you using Decimal correctly?
lovee
4
690
Other Decks in Programming
See All in Programming
ActiveSupport::Notifications supporting instrumentation of Rails apps with OpenTelemetry
ymtdzzz
1
230
AWS Lambdaから始まった Serverlessの「熱」とキャリアパス / It started with AWS Lambda Serverless “fever” and career path
seike460
PRO
1
260
リアーキテクチャxDDD 1年間の取り組みと進化
hsawaji
1
220
Arm移行タイムアタック
qnighy
0
320
Click-free releases & the making of a CLI app
oheyadam
2
120
PHP でアセンブリ言語のように書く技術
memory1994
PRO
1
170
シールドクラスをはじめよう / Getting Started with Sealed Classes
mackey0225
4
640
Generative AI Use Cases JP (略称:GenU)奮闘記
hideg
1
290
Realtime API 入門
riofujimon
0
150
[Do iOS '24] Ship your app on a Friday...and enjoy your weekend!
polpielladev
0
100
TypeScript Graph でコードレビューの心理的障壁を乗り越える
ysk8hori
2
1.1k
2024/11/8 関西Kaggler会 2024 #3 / Kaggle Kernel で Gemma 2 × vLLM を動かす。
kohecchi
5
920
Featured
See All Featured
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
28
2k
Building Applications with DynamoDB
mza
90
6.1k
The Cost Of JavaScript in 2023
addyosmani
45
6.7k
Bash Introduction
62gerente
608
210k
Measuring & Analyzing Core Web Vitals
bluesmoon
4
120
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
10
720
Unsuck your backbone
ammeep
668
57k
The Language of Interfaces
destraynor
154
24k
Rails Girls Zürich Keynote
gr2m
94
13k
Docker and Python
trallard
40
3.1k
Build your cross-platform service in a week with App Engine
jlugia
229
18k
VelocityConf: Rendering Performance Case Studies
addyosmani
325
24k
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