Upgrade to Pro — share decks privately, control downloads, hide ads and more …

SwiftUIでUIViewを使うときのレイアウト処理 / Layout process when using UIKit view in SwiftUI

Mike Apurin
December 17, 2021

SwiftUIでUIViewを使うときのレイアウト処理 / Layout process when using UIKit view in SwiftUI

Mike Apurin

December 17, 2021
Tweet

More Decks by Mike Apurin

Other Decks in Technology

Transcript

  1. ࣗݾ঺հ Apurin Mikhail ΞϓϦϯɾϛϋΠϧ auramagi apurin.me 􀒡 - ΏΊΈͷiOSΤϯδχΞ -

    ࠓݱࡏϩγΞ͔ΒϦϞʔτϫʔΫ - ژ౎ → ϞεΫϫͷఱؾΪϟοϓ͸͙͍͑ (+13° → -17°) - ିग़ͷM1 Max MacBook Proಧ͘௚લʹߦͬͨͷ͕੯͍͠
  2. struct LabelRepresentable: UIViewRepresentable { let text: String func makeUIView(context: Context)

    -> UILabel { .init() } func updateUIView(_ uiView: UILabel, context: Context) { uiView.numberOfLines = 0 uiView.text = text } } UIViewRepresentableΛॻ͍ͯΈΔ ؆୯ʹॻ͚·͢ʂ ඞਢϝιου: - Ϗϡʔੜ੒ makeUIView - Ϗϡʔߋ৽ updateUIView
  3. struct LabelRepresentable_Previews: PreviewProvider { static var previews: some View {

    LabelRepresentable( text: "Journey before destination" ) } } ΍ͬͨʂ ɻɻɻ Μʁ தԝἧ͑ʹͳ͍ͬͯͳ͍ʂʂ PreviewͰ࢖ͬͯΈΔ
  4. struct LabelRepresentable_Previews: PreviewProvider { static var previews: some View {

    LabelRepresentable( text: "Journey before destination" ) .border(.red) .padding() } } ը໘શମͷαΠζΛऔ͍ͬͯΔ SwiftUI ͷ Text ͷΑ͏ʹɺͽͬͨΓͷαΠζΛͱͬͯ
 தԝἧ͑ʹͳΔΠϝʔδ͕ͩͬͨɺ·͍͍͔͋ʁ PreviewͰ࢖ͬͯΈΔ
  5. struct LabelRepresentable_Previews: PreviewProvider { static var previews: some View {

    LabelRepresentable( text: "To love the journey is to accept no such 
 end. I have found, through painful experience, 
 that the most important step a person can take 
 is always the next one." ) .border(.red) .padding() } } PreviewͰ࢖ͬͯΈΔ Ξ ͩΊͩʔ orz
  6. SwiftUIͷϨΠΞ΢τॲཧ WWDC 2019 — Building Custom Views with SwiftUI ͦ΋ͦ΋SwiftUIͰͲ͏΍ͬͯҐஔͱαΠζ͕


    ܾΊΒΕΔͷ͔ʁ ϨΠΞ΢τॲཧͷৄࡉ͸ඇެ։ͳͷͰ
 υΩϡϝϯτ͕΄΅ͳ͍ 😔 جຊͷॲཧ͸ҎԼͷεςοϓ͔ΒͳΔ 1. ਌View͕ࢠViewʹαΠζΛఏҊ͢Δ 2. ࢠView͕ࣗ෼ͷαΠζΛܾΊΔ 3. ਌View͕ࣗ෼ͷ࠲ඪۭؒͰࢠViewΛ഑ஔ͢Δ
  7. SwiftUIͷϨΠΞ΢τॲཧ ViewͷαΠζ͸࣍ͷܗʹͳ͍ͬͯΔͱਪଌͰ͖Δ struct Dimension { let min: CGFloat let ideal:

    CGFloat let max: CGFloat } - min: ࠷௿஋ - ideal: ཧ૝αΠζ - max: ࠷ߴ஋ - ؔ܎Λݫक: min <= ideal <= max
  8. SwiftUIͷϨΠΞ΢τॲཧ ఏҊαΠζ͸࣍ͷܗͰ౉͞ΕΔͱਪଌͰ͖Δ struct ProposedSize { let width: CGFloat? let height:

    CGFloat? } - ஋͕ࢦఆ͞Ε͍ͯΔ৔߹͸ɺͦΕΛϕʔεʹαΠζΛܭࢉ - nilͷ৔߹͸ɺViewࣗ਎ͷidealαΠζΛͱΔ - . fi xedSizeͰnilʹมߋ͞ΕΔ
  9. SwiftUIͷϨΠΞ΢τॲཧ ௨ৗͷ৔߹͸ɺҎԼͷܭࢉ͕ࣜదԠ͞ΕΔ if let proposedWidth = proposedSize.width { // dimensionsͰ্ݶ஋ɾԼݶ஋Λ཈͑Δ

    width = max( dimensions.min, min(dimensions.max, proposedWidth) ) } else { width = dimensions.ideal } // height΋ಉ༷
  10. Color.mint .frame( minWidth: 100, maxWidth: 200, minHeight: 100, maxHeight: 200

    ) .frame(width: 300, height: 300) .border(.mint) SwiftUIͷϨΠΞ΢τॲཧ 📱 W: 390 H: 763 .frame(minWidth: 200, …) .frame(width: 300, height: 300) Color ఏҊαΠζ ࣮αΠζ W: 300 H: 300 W: 200 H: 200 W: 300 H: 300 W: 200 H: 200 W: 200 H: 200
  11. Text("Hello YUMEMI.swift") .fixedSize() .border(.mint) .frame(width: 300, height: 300) .border(.mint) SwiftUIͷϨΠΞ΢τॲཧ

    📱 W: 390 H: 763 .fixedSize() .frame(width: 300, height: 300) Text("Hello YUMEMI.swift") ఏҊαΠζ ࣮αΠζ W: 300 H: 300 W: nil H: nil W: 300 H: 300 W: 149.7 H: 20.3 W: 149.7 H: 20.3
  12. UIViewRepresentable AutoLayoutͷintrinsicαΠζͱpriorityΛݩʹͯ͠αΠζΛܭࢉ Intrinsic size Compression Resistance Hugging ݁Ռ
 (min …

    ideal … max) (-1) - - 0 … 0 … ∞ x < 750 < 750 0 … x … ∞ x < 750 >= 750 0 … x … x x < 750 < 750 x … x … ∞ x >= 750 >= 750 x … x … x -1 = UIView.noIntrinsicMetric 750 = UILayoutPriority.defaultHigh
  13. UIViewRepresentable 1 ͱ 2 ͷڍಈ͸ௐ੔Ͱ͖Δඇެ։API͕͋Δ ⚠ ඇެ։APIͳͷͰϦϦʔεϏϧυʹೖΕͪΌμϝ ⚠ public protocol

    UIViewRepresentable { // 1 (AutoLayoutϓϩύςΟ → ͳΕΔαΠζ) func _overrideLayoutTraits( _ layoutTraits: inout SwiftUI._LayoutTraits, for uiView: Self.UIViewType ) // 2 (ఏҊαΠζ → ࣮αΠζ) func _overrideSizeThatFits( _ size: inout CoreGraphics.CGSize, in proposedSize: SwiftUI._ProposedSize, uiView: Self.UIViewType ) }
  14. import RepresentableKit struct UILabel_Previews: PreviewProvider { static var previews: some

    View { UIViewAdaptor { let view = UILabel() view.numberOfLines = 0 view.text = "To love the journey is to accept no 
 such end. I have found, through painful experience, that the most important step a person can take is always the next one." return view } .padding() } } RepresentableKitͷ঺հ UIViewRepresentableͷαΠζܭࢉΛந৅Խͯ͠
 ΑΓ؆୯ʹ࢖͑ΔΑ͏ʹϔϧύʔϥΠϒϥϦΛ
 ࡞Γ·ͨ͠ɻ
 https://github.com/yumemi-inc/RepresentableKit