Slide 1

Slide 1 text

No Story No Board for iOS UI࣮૷ษڧձ

Slide 2

Slide 2 text

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 { } }

Slide 3

Slide 3 text

ࠓ·ͰͷาΈ

Slide 4

Slide 4 text

ࠓ·ͰͷาΈ ͓ɺ΍ͬͺΈΜͳ Storyboard ݏ͍΍Μ͚
 !

Slide 5

Slide 5 text

ࠓ·ͰͷาΈ

Slide 6

Slide 6 text

ࠓ·ͰͷาΈ ٸͳొஃͰ͔ͨ͠Β४උෆ଍Ͱશવ஻Εͳ͔ͬͨ
 "

Slide 7

Slide 7 text

ࠓ·ͰͷาΈ

Slide 8

Slide 8 text

ࠓ·ͰͷาΈ HITMAN ʹϋϚͬͯͦ΋ͦ΋४උͰ͖ͳ͔ͬͨ
 "

Slide 9

Slide 9 text

ࡾ౓໨ͷਖ਼௚ʹͳΔͷ͔"

Slide 10

Slide 10 text

໔੹੠໌ ͜ͷൃද͸ Storyboard Λ dis ΔൃදͰ͢ ͕ɺผʹօʹ͜ͷߟ͑Λԡ͠෇͚͍ͨͱ͸ࢥΘͳ͍ ͜ͷൃද͸ϋʔυίʔσΟϯά࠷ߴͱ͸ݴ͍ͬͯͳ͍ Storyboard ΋ϋʔυίʔσΟϯά΋ͦΕͧΕͷ᠘͕͋Δ ͦ΋ͦ΋ࢲ͸ GUI Ͱ GUI Λ࡞Δ͜ͱࣗମʹ͸େࢍ੒ ͨͩ Storyboard ͷ࣮૷͕࢒೦͗͢ΔͱࢥͬͯΔ͚ͩ

Slide 11

Slide 11 text

ࢲ͕ Storyboard Λ࢖Θͳ͍ཧ༝ʢ1ʣ Auto Layout ͷ੍໿Λ࢖͏ View ͕૿͑Δͱ੍໿͕രൃ తʹ૿͑Δ ʮ͜ͷ View ͷ͜ͷ੍໿ʯ͕ ୳ͮ͠Β͍

Slide 12

Slide 12 text

ࢲ͕ Storyboard Λ࢖Θͳ͍ཧ༝ʢ2ʣ Swift ͳͷʹ IUO Λ࢖͏ UIViewController ͷϥΠϑ αΠΫϧΛ೺Ѳ͠ͳ͍ͱ མͪΔ͜ͱ΋͋Δ ؾ࣋ͪѱ͍

Slide 13

Slide 13 text

ৄ͘͠͸ http://qiita.com/lovee/items/acfc9d0f1ffa7207b38b
 Λ͝ཡ͍ͩ͘͞#

Slide 14

Slide 14 text

One more thing!

Slide 15

Slide 15 text

UIStackView Auto Layout LayoutKit Manual Layout PinLayout ※ग़యɿhttps://github.com/mirego/PinLayout/blob/master/docs/Benchmark.md 銙闗#WVQ.C[QWV闖㢚閴聮閳闋闇#

Slide 16

Slide 16 text

ͦΕͰ΋ Auto Layout ࢖͍͍ͨํ PureLayout macOS / iOS ྆ํͰར༻Ͱ ͖Δ Swift / Objective-C ྆ํͰ ར༻Ͱ͖Δ AutoLayout ੍໿Λ؆ܿʹɺ ͔ͭൺֱతʹ෼͔Γ΍͢ ͘ॻ͚Δ ͔ͳΓॆ࣮͍ͯ͠Δࢿྉ

Slide 17

Slide 17 text

ͦΕͰ΋ Auto Layout ࢖͍͍ͨํ SnapKit macOS / iOS / tvOS શ෦ར ༻Ͱ͖Δ Swift ͷߏจಛ௃Λ࠷େݶ ʹҾ͖ग़͍ͯ͠Δ গ͠௕͘ͳΔ͕ɺඇৗʹ ෼͔Γ΍͍͢จ๏ ඇৗʹॆ࣮͍ͯ͠Δެࣜ ࢿྉ

Slide 18

Slide 18 text

–Elvis Shi l΍ͬͺΓ๻͸ɺ"VUP-BZPVUΛ࢖Θͣʹ
 ίʔυͰ6*Λ૊Έ͍ͨz

Slide 19

Slide 19 text

㘦㖽㘼㗧㙟㘗㘕㘙㘻㘒ଡ଼㘀㘬㘬㙔 UIView / UIViewController ͷϥΠϑαΠΫϧΛཧղ͢Δ ௚઀ର৅Λ࿔Δ෼ɺର৅ʹৄ͘͠ͳΔඞཁ͕͋Δ ϨΠΞ΢τΛઃఆ͢ΔϓϩύςΟʔΛཧղ͢Δ ؒҧͬͨϓϩύςΟʔ΁ͷॻ͖ࠐΈ͸ࢥΘ͵όάΛট͘ αʔυύʔςΟʔ੡ϥΠϒϥϦʔΛཧղ͢Δ ศརͳ൓໘ɺࢥͬͯΔͷͱಈ͖͕ҧ͏Մೳੑ΋͋Δ

Slide 20

Slide 20 text

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?

Slide 21

Slide 21 text

UIView / UIViewController ͷϥΠϑαΠΫϧΛཧղ͢Δ ͸Ͳ͏΍ͬͯ൑ఆ͍ͯ͠Δͷ͔ʁ Needs layout? setNeedsLayout() Λݺͼग़ͨ͠ σόΠε͕ճసͨ͠ ࢠϏϡʔΛ௥Ճ΍࡟আΛͨ͠ ʢUIScrollView Ͱ͋ΔࢠϏϡʔʣ͕εΫϩʔϧͨ͠ ࣗ෼ͷࢠϏϡʔͷ frame ΍ transform ͳͲ͕มߋ͞Εͨ ͳͲͳͲ…

Slide 22

Slide 22 text

UIView / UIViewController ͷϥΠϑαΠΫϧΛཧղ͢Δ ͸Ͳ͏΍ͬͯ൑ఆ͍ͯ͠Δͷ͔ʁ Needs layout? setNeedsLayout() Λݺͼग़ͨ͠ σόΠε͕ճసͨ͠ ࢠϏϡʔΛ௥Ճ΍࡟আΛͨ͠ ʢUIScrollView Ͱ͋ΔࢠϏϡʔʣ͕εΫϩʔϧͨ͠ ࣗ෼ͷࢠϏϡʔͷ frame ΍ transform ͳͲ͕มߋ͞Εͨ ͳͲͳͲ… ࣗ෼ͷ frame ΍ transform Λมߋ͢Ε͹
 ਌ͷ layoutSubviews() ΋ݺ͹ΕΔʂ ࣗ෼ͷ frame ΍ transform ͸
 ඞͣ਌ʹมߋͯ͠΋Β͓͏ʂ

Slide 23

Slide 23 text

–Elvis Shi l6*7JFXͷGSBNF΍USBOTGPSN͸ɺ
 ࣗ෼ͷͰ͸ͳ͘ɺ਌ͷ΋ͷz

Slide 24

Slide 24 text

ϨΠΞ΢τΛઃఆ͢ΔϓϩύςΟʔΛཧղ͢Δ view.frame = CGRect(x: 0, y: 0, width: 200, height: 200)

Slide 25

Slide 25 text

ϨΠΞ΢τΛઃఆ͢ΔϓϩύςΟʔΛཧղ͢Δ view.frame = CGRect(x: 0, y: 0, width: 200, height: 200) view.transform = view.transform.rotated(by: .pi / 4)

Slide 26

Slide 26 text

ϨΠΞ΢τΛઃఆ͢ΔϓϩύςΟʔΛཧղ͢Δ view.frame = CGRect(x: 0, y: 0, width: 200, height: 200) view.transform = view.transform.rotated(by: .pi / 4) view.frame.size.width = 100

Slide 27

Slide 27 text

ϨΠΞ΢τΛઃఆ͢ΔϓϩύςΟʔΛཧղ͢Δ 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 Λ൒෼ʹͨ͠Β
 ෯΋ߴ͞΋ཱͪҐஔ΋શ͕ͯมΘͬͨ"

Slide 28

Slide 28 text

※ग़యɿhttps://developer.apple.com/documentation/uikit/uiview/1622621-frame

Slide 29

Slide 29 text

΋͠ transform ϓϩύςΟʔ͕
 identity Ͱͳ͚Ε͹ɺ ͜ͷϓϩύςΟʔͷ஋͸ະఆٛͱͳΓɺ ແࢹ͢΂͖Ͱ͋Δɻ ʢҙ༁ɿ৮Δͳ΄ͬͱ͚ʂʣ ※ग़యɿhttps://developer.apple.com/documentation/uikit/uiview/1622621-frame

Slide 30

Slide 30 text

frame Λ࿔Γ͍ͨͳΒ ୅ΘΓʹ center ͱ bounds.size ͷํΛ ࿔Εʂ ※ग़యɿhttps://developer.apple.com/documentation/uikit/uiview/1622621-frame

Slide 31

Slide 31 text

ϨΠΞ΢τΛઃఆ͢ΔϓϩύςΟʔΛཧղ͢Δ view.bounds.size = CGSize(width: 100, height: 100) view.center = CGPoint(x: base.bounds.midX, y: base.bounds.midY)

Slide 32

Slide 32 text

ϨΠΞ΢τΛઃఆ͢ΔϓϩύςΟʔΛཧղ͢Δ view.bounds.size = CGSize(width: 100, height: 100) view.center = CGPoint(x: base.bounds.midX, y: base.bounds.midY) view.layer.anchorPoint.y = 0

Slide 33

Slide 33 text

ϨΠΞ΢τΛઃఆ͢ΔϓϩύςΟʔΛཧղ͢Δ 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 Λมߋͨ͠Β
 ࣗ෼ͷ৔ॴ͕มΘͬͨ"

Slide 34

Slide 34 text

※ग़యɿhttps://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreAnimation_guide/CoreAnimationBasics/ CoreAnimationBasics.html#//apple_ref/doc/uid/TP40004514-CH2-SW3

Slide 35

Slide 35 text

anchorPoint ͱϨΠϠʔͷ
 ϙδγϣχϯάͷؔ܎ʹ͍ͭͯ ʢҙ༁ɿcenter ͕ࢦͯ͠Δͷ͸
 anchorPoint ͷ
 ৔ॴͳΜ΍ʂʣ ※ग़యɿhttps://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreAnimation_guide/CoreAnimationBasics/ CoreAnimationBasics.html#//apple_ref/doc/uid/TP40004514-CH2-SW3

Slide 36

Slide 36 text

–Elvis Shi lUSBOTGPSN͕ॳظ஋͡Όͳ͍Մೳੑ͕͋Ε͹ɺ
 GSBNFΛઃఆͤͣʹ
 CPVOETTJ[FͱDFOUFSΛઃఆ͠Α͏z

Slide 37

Slide 37 text

αʔυύʔςΟʔ੡ϥΠϒϥϦʔΛཧղ͢Δ

Slide 38

Slide 38 text

αʔυύʔςΟʔ੡ϥΠϒϥϦʔΛཧղ͢Δ ݟͨײ͡Ͱ͸Ͳ͏΍Β
 frame ʹ௚઀ॻ͖ࠐΜͰͦ͏$

Slide 39

Slide 39 text

αʔυύʔςΟʔ੡ϥΠϒϥϦʔΛཧղ͢Δ segmented.transform = segmented.transform.rotated(by: .pi/4)

Slide 40

Slide 40 text

αʔυύʔςΟʔ੡ϥΠϒϥϦʔΛཧղ͢Δ segmented.transform = segmented.transform.rotated(by: .pi/4) ΍͸Γ transform Λ࿔ͬͨΒ
 ϨΠΞ΢τͰόάͬͨ"

Slide 41

Slide 41 text

NotAutoLayout https://github.com/el-hoshino/NotAutoLayout

Slide 42

Slide 42 text

αʔυύʔςΟʔ੡ϥΠϒϥϦʔΛཧղ͢Δ segmented.transform = segmented.transform.rotated(by: .pi/4)

Slide 43

Slide 43 text

αʔυύʔςΟʔ੡ϥΠϒϥϦʔΛཧղ͢Δ segmented.transform = segmented.transform.rotated(by: .pi/4) bounds.size ͱ center Λઃఆ͍ͯ͠ΔͷͰɺ transform Λมߋͯ͠΋ϨΠΞ΢τ่Ε͸͠ͳ͍

Slide 44

Slide 44 text

let titleViewLayout = Layout .makeCustom(x: { _ in 0 }, y: { _ in 0 }, width: { $0.width }, height: { _ in 60 }) baseView.addSubview(titleView, constantLayout: titleViewLayout) NotAutoLayout 1.0

Slide 45

Slide 45 text

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ʢԾʣ

Slide 46

Slide 46 text

–Elvis Shi l/PU"VUP-BZPVUΛͥͻࢼͯ͠Έ͍ͯͩ͘͞
 'FFECBDLͱ4UBSΛ͓଴͓ͪͯ͠Γ·͢z