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

Refactor with using `available` and `deprecated`

417.72KI
December 22, 2022

Refactor with using `available` and `deprecated`

potatotips#80

417.72KI

December 22, 2022
Tweet

More Decks by 417.72KI

Other Decks in Programming

Transcript

  1. !@LJ
    BWBJMBCMFͱEFQSFDBUFEΛ࢖ͬͯ
    ޮ཰త͔ͭ҆શʹ
    ϦϑΝΫλϦϯάΛਐΊΔ

    QPUBUPUJQT

    View Slide

  2. "CPVUNF
    struct Me {


    let name = "Takuhiro Muta"


    let aka = "417.72KI"


    let company = "(redacted)"


    let twitter = "417_72ki"


    let qiita = "417_72ki"


    let gitHub = "417-72KI"


    let products = [


    "MockUserDefaults",


    "MultipartFormDataParser",


    "BuildConfig.swift",


    "SSGH"


    ]


    let contributing = [


    "Danger-Swift",


    "octokit.swift",


    "etc..."


    ]


    }

    View Slide

  3. طଘίʔυʹUZQPΛݟ͚ͭͨΒ
    Ͳ͏͠·͔͢ʁ

    View Slide

  4. w मਖ਼͢Δ
    w ݟͳ͔ͬͨ͜ͱʹ͢Δ

    View Slide

  5. w मਖ਼͢Δ
    w 3FGBDUPS3FOBNF
    w 'JOEBOE3FQMBDFJO1BDLBHF
    w ݟͳ͔ͬͨ͜ͱʹ͢Δ

    View Slide

  6. w मਖ਼͢Δ
    w 3FGBDUPS3FOBNF
    w 'JOEBOE3FQMBDFJO1BDLBHF
    w ݟͳ͔ͬͨ͜ͱʹ͢Δ

    View Slide

  7. 3FGBDUPS3FOBNF

    View Slide

  8. 😩

    View Slide

  9. w मਖ਼͢Δ
    w 3FGBDUPS3FOBNF
    w 'JOEBOE3FQMBDFJO1BDLBHF
    w ݟͳ͔ͬͨ͜ͱʹ͢Δ

    View Slide

  10. 'JOEBOE3FQMBDFJO1BDLBHF

    View Slide

  11. 'JOEBOE3FQMBDFJO1BDLBHF
    w Ұݟྑͦ͞͏ʹݟ͑Δ͕
    w ͤʔͷͰҰ੪ʹॻ͖׵ΘΔ
    w ໢ཏੑ͸େৎ෉ʁ
    w ౰֘GVODUJPOҎ֎ʹಉ͡UZQP͕͋ͬͨ࣌ͦͬͪ΋มΘΔ
    w ςετ͖͠ΕΔʁ
    w UZQPΛमਖ਼ͨ݁͠ՌผͷGVODUJPOͱඃͬͨ
    w ҙਤͤ͵όάͷ஀ੜ
    🤔

    View Slide

  12. 'JOEBOE3FQMBDFJO1BDLBHF
    // A.swift


    func doSomesing() {


    // do something


    }


    // C.swift


    func doSomething(with foo: Foo = .init()) {


    // do something with `foo`


    }
    // B.swift


    func call() {


    doSomesing()


    }


    // D.swift


    func callWithFoo() {


    doSomething()


    }

    View Slide

  13. 'JOEBOE3FQMBDFJO1BDLBHF
    // A.swift


    func doSomething() {


    // do something


    }


    // C.swift


    func doSomething(with foo: Foo = .init()) {


    // do something with `foo`


    }
    // B.swift


    func call() {


    doSomething()


    }


    // D.swift


    func callWithFoo() {


    doSomething()


    }
    😱

    View Slide

  14. w मਖ਼͢Δ
    w 3FGBDUPS3FOBNF
    w 'JOEBOE3FQMBDFJO1BDLBHF
    w ݟͳ͔ͬͨ͜ͱʹ͢Δ

    View Slide

  15. w मਖ਼͢Δ
    w 3FGBDUPS3FOBNF
    w 'JOEBOE3FQMBDFJO1BDLBHF
    w 6TFABWBJMBCMFABOEAEFQSFDBUFEA
    w ݟͳ͔ͬͨ͜ͱʹ͢Δ

    View Slide

  16. BWBJMBCMFʹ͍ͭͯ
    BWBJMBCMFͱ͸
    w ʮಛఆͷ04όʔδϣϯ͔Β࢖͑Δ࢖͑ͳ͘ͳΔʯͱ͍ͬͨ৘ใΛऔΓѻ͏
    BUUSJCVUF
    w Ϗϧυ࣌ʹܯࠂΤϥʔͷܗͰϑΟʔυόοΫͯ͘͠ΕΔ

    View Slide

  17. BWBJMBCMFʹ͍ͭͯ
    ओͳΦϓγϣϯ
    w ܯࠂ
    w EFQSFDBUFEඇਪ঑ όʔδϣϯলུՄ

    w ϏϧυΤϥʔ
    w PCTPMFUFEഇࢭ όʔδϣϯলུෆՄ

    w VOBWBJMBCMFར༻ෆՄ όʔδϣϯࢦఆෆՄ

    View Slide

  18. BWBJMBCMFʹ͍ͭͯ
    ओͳΦϓγϣϯ
    w ͦͷଞ
    w SFOBNFEϦωʔϜઌͷ"1*GVODUJPO໊

    ࢦఆ͢Δͱ9DPEF্ͰαδΣετΑ͠ͳʹஔ׵ͯ͘͠ΕΔ
    w NFTTBHFܯࠂΤϥʔϝοηʔδ

    View Slide

  19. BWBJMBCMFEFQSFDBUFEΛ࢖ͬͯUZQPΛमਖ਼
    ϝϦοτ
    w ཁमਖ਼ՕॴͷಛఆΛίϯύΠϥʹؙ౤͛Ͱ͖Δ
    w શ෦ม͑Δඞཁ͕ແ͍ͷͰஈ֊తʹϦϑΝΫλϦϯάΛਐΊΒΕΔ
    w FYվमର৅ʹͳͬͨΒରԠ͢Δ
    w FYςετίʔυͷ͋Δݺͼग़͠ݩ͔ΒରԠ͍ͯ͘͠
    w ӨڹൣғΛ࠷খݶʹ཈͑ΒΕΔ

    View Slide

  20. BWBJMBCMFEFQSFDBUFEΛ࢖ͬͯUZQPΛमਖ਼
    σϝϦοτ
    w Өڹൣғ͕ଟ͚Ε͹ଟ͍΄Ͳܯࠂ਺͕૿͑Δ
    w ಉ͡಺༰ͷܯࠂ͕ζϥοͱฒͿ
    w $*ͷग़ྗΛπʔϧͰऔͬͯͨΓ͍ͯ͠Δͱπϥ͍͔΋
    w SFOBNFEͰͷࣗಈม׵͸ҰׅͰͰ͖ͳ͍
    w ·ͱΊͯ΍Ζ͏ͱ͢Δͱෆศ

    View Slide

  21. func doSomesing() {


    // do something


    }

    View Slide

  22. func doSomesing() {


    doSomething()


    }


    func doSomething() {


    // do something


    }

    View Slide

  23. @available(*, deprecated, renamed: "doSomething()")


    func doSomesing() {


    doSomething()


    }


    func doSomething() {


    // do something


    }

    View Slide

  24. View Slide

  25. View Slide

  26. View Slide

  27. Ԡ༻ฤ

    View Slide

  28. αϙʔτόʔδϣϯͷؔ܎Ͱ
    ࢖͑ͳ͍"1*Λ࢖͍͍ͨ

    View Slide

  29. αϙʔτόʔδϣϯͷؔ܎Ͱ࢖͑ͳ͍"1*
    ˞J04ͷ"QQΛ૝ఆ
    w JGBWBJMBCMFΛ࢖ͬͯ
    w 8PSLBSPVOEͱซ༻͢Δ
    w ্ҐόʔδϣϯͷΈ࢖͑ΔΑ͏ʹ͢Δ
    w FY
    w "UUSJCVUFE4USJOH J04d

    w QSFTFOUBUJPO%FUFOUT J04d

    View Slide

  30. αϙʔτόʔδϣϯͷؔ܎Ͱ࢖͑ͳ͍"1*
    ˞J04ͷ"QQΛ૝ఆ
    w JGBWBJMBCMFΛ࢖ͬͯ
    w 8PSLBSPVOEͱซ༻͢Δ
    w ্ҐόʔδϣϯͷΈ࢖͑ΔΑ͏ʹ͢Δ
    w FY
    w "UUSJCVUFE4USJOH J04d

    w QSFTFOUBUJPO%FUFOUT J04d

    View Slide

  31. "UUSJCVUFE4USJOH
    var attributedString: AttributedString { // ← 'AttributedString' is


    only available in iOS 15 or newer


    var str = AttributedString("Foo Bar Baz Qux Quux")


    if let range = str.range(of: "Bar") {


    str[range].foregroundColor = .red


    }


    if let range = str.range(of: "Baz") {


    str[range].font = .title


    }


    if let range = str.range(of: "Qux") {


    str[range].font = .footnote


    str[range].foregroundColor = .green


    }


    return str


    }
    var body: some View {


    VStack {


    Text(attributedString) // ← 'init(_:)'


    is only available in iOS 15.0 or newer


    }


    }


    View Slide

  32. "UUSJCVUFE4USJOH
    @available(iOS 15, *)


    var attributedString: AttributedString {


    var str = AttributedString("Foo Bar Baz Qux Quux")


    if let range = str.range(of: "Bar") {


    str[range].foregroundColor = .red


    }


    if let range = str.range(of: "Baz") {


    str[range].font = .title


    }


    if let range = str.range(of: "Qux") {


    str[range].font = .footnote


    str[range].foregroundColor = .green


    }


    return str


    }
    var body: some View {


    VStack {


    Text(attributedString) // ← 'init(_:)'


    is only available in iOS 15.0 or newer


    }


    }


    View Slide

  33. "UUSJCVUFE4USJOH
    var body: some View {


    VStack {


    if #available(iOS 15, *) {


    Text(attributedString)


    } else {


    Text("Foo")


    + Text(" ")


    + Text("Bar")


    .foregroundColor(.red)


    + Text(" ")


    + Text("Baz")


    .font(.title)


    + Text(" ")


    + Text("Qux")


    .font(.footnote)


    .foregroundColor(.green)


    + Text(" ")


    + Text("Quux")


    }


    }


    }
    @available(iOS 15, *)


    var attributedString: AttributedString {


    var str = AttributedString("Foo Bar Baz Qux Quux")


    if let range = str.range(of: "Bar") {


    str[range].foregroundColor = .red


    }


    if let range = str.range(of: "Baz") {


    str[range].font = .title


    }


    if let range = str.range(of: "Qux") {


    str[range].font = .footnote


    str[range].foregroundColor = .green


    }


    return str


    }

    View Slide

  34. "UUSJCVUFE4USJOH
    var body: some View {


    VStack {


    if #available(iOS 15, *) {


    Text(attributedString)


    } else {


    AttributedText {


    Text("Foo")


    Text(" ")


    Text("Bar")


    .foregroundColor(.red)


    Text(" ")


    Text("Baz")


    .font(.title)


    Text(" ")


    Text("Qux")


    .font(.footnote)


    .foregroundColor(.green)


    Text(" ")


    Text("Quux")


    }


    }


    }


    }
    struct AttributedText: View {


    typealias Body = Text


    var text: Text


    init(@Builder builder: () -> Text) {


    text = builder()


    }


    var body: Text {


    text


    }


    }


    extension AttributedText {


    @resultBuilder


    enum Builder { ɾɾɾ }


    }

    View Slide

  35. JGBWBJMBCMFͷपғ͸೥ޙʹ
    ٕज़తෛ࠴ʹͳΔ͜ͱ͕֬ఆ͍ͯ͠Δ
    🤔

    View Slide

  36. Ͱ΋೥ޙʹ֮͑ͯΔอূ͸ແ͍
    😅

    View Slide

  37. "UUSJCVUFE4USJOH
    ໿ଋ͞Εٕͨज़తෛ࠴Λ຤୅·Ͱ͓֮͑ͯͨ͘Ίʹ
    var body: some View {


    VStack {


    AttributedText {


    Text("Foo")


    Text(" ")


    Text("Bar")


    .foregroundColor(.red)


    Text(" ")


    Text("Baz")


    .font(.title)


    Text(" ")


    Text("Qux")


    .font(.footnote)


    .foregroundColor(.green)


    Text(" ")


    Text("Quux")


    }


    }


    }
    struct AttributedText: View {


    typealias Body = Text


    var text: Text


    init(@Builder builder: () -> Text) {


    text = builder()


    }


    var body: Text {


    text


    }


    }


    extension AttributedText {


    @resultBuilder


    enum Builder { ɾɾɾ }


    }

    View Slide

  38. "UUSJCVUFE4USJOH
    .JOJNVN%FQMPZNFOU5BSHFU͕ҎԼͷؒ͸ܯࠂ͕ग़ͳ͍
    @available(iOS, deprecated: 15.0, obsoleted: 16.0,


    message: "Use `Text` with `AttributedString`")


    struct AttributedText: View {


    typealias Body = Text


    var text: Text


    init(@Builder builder: () -> Text) {


    text = builder()


    }


    var body: Text {


    text


    }


    }


    @available(iOS, deprecated: 15.0, obsoleted: 16.0,


    message: "Use `Text` with `AttributedString`")


    extension AttributedText {


    @resultBuilder


    enum Builder { ɾɾɾ }


    }
    var body: some View {


    VStack {


    AttributedText {


    Text("Foo")


    Text(" ")


    Text("Bar")


    .foregroundColor(.red)


    Text(" ")


    Text("Baz")


    .font(.title)


    Text(" ")


    Text("Qux")


    .font(.footnote)


    .foregroundColor(.green)


    Text(" ")


    Text("Quux")


    }


    }


    }

    View Slide

  39. "UUSJCVUFE4USJOH
    .JOJNVN%FQMPZNFOU5BSHFUΛʹͨ͠Βܯࠂ͕ग़Δ
    @available(iOS, deprecated: 15.0, obsoleted: 16.0,


    message: "Use `Text` with `AttributedString`")


    struct AttributedText: View {


    typealias Body = Text


    var text: Text


    init(@Builder builder: () -> Text) {


    text = builder()


    }


    var body: Text {


    text


    }


    }


    @available(iOS, deprecated: 15.0, obsoleted: 16.0,


    message: "Use `Text` with `AttributedString`")


    extension AttributedText {


    @resultBuilder


    enum Builder { ɾɾɾ }


    }
    var body: some View {


    VStack {


    AttributedText { // ←
    'AttributedText' was deprecated in iOS
    15.0: Use `Text` with `AttributedString`


    Text("Foo")


    Text(" ")


    Text("Bar")


    .foregroundColor(.red)


    Text(" ")


    Text("Baz")


    .font(.title)


    Text(" ")


    Text("Qux")


    .font(.footnote)


    .foregroundColor(.green)


    Text(" ")


    Text("Quux")


    }


    }


    }

    View Slide

  40. "UUSJCVUFE4USJOH
    .JOJNVN%FQMPZNFOU5BSHFUΛʹͨ͠ΒϏϧυΤϥʔʹ
    @available(iOS, deprecated: 15.0, obsoleted: 16.0,


    message: "Use `Text` with `AttributedString`")


    struct AttributedText: View {


    typealias Body = Text


    var text: Text


    init(@Builder builder: () -> Text) {


    text = builder()


    }


    var body: Text {


    text


    }


    }


    @available(iOS, deprecated: 15.0, obsoleted: 16.0,


    message: "Use `Text` with `AttributedString`")


    extension AttributedText {


    @resultBuilder


    enum Builder { ɾɾɾ }


    }
    var body: some View {


    VStack {


    AttributedText { // ←
    'AttributedText' is unavailable in iOS:
    Use `Text` with `AttributedString`


    Text("Foo")


    Text(" ")


    Text("Bar")


    .foregroundColor(.red)


    Text(" ")


    Text("Baz")


    .font(.title)


    Text(" ")


    Text("Qux")


    .font(.footnote)


    .foregroundColor(.green)


    Text(" ")


    Text("Quux")


    }


    }


    }

    View Slide

  41. "UUSJCVUFE4USJOH
    JGBWBJMBCMF
    \^FMTF\^ͰׅΒΕΔͱܯࠂ͕ग़ͳ͍
    var body: some View {


    VStack {


    if #available(iOS 15, *) {


    Text(attributedString)


    } else {


    AttributedText {


    Text("Foo")


    Text(" ")


    Text("Bar")


    .foregroundColor(.red)


    Text(" ")


    Text("Baz")


    .font(.title)


    Text(" ")


    Text("Qux")


    .font(.footnote)


    .foregroundColor(.green)


    Text(" ")


    Text("Quux")


    }


    }


    }


    }
    @available(iOS, deprecated: 15.0, obsoleted: 16.0,


    message: "Use `Text` with `AttributedString`")


    struct AttributedText: View {


    typealias Body = Text


    var text: Text


    init(@Builder builder: () -> Text) {


    text = builder()


    }


    var body: Text {


    text


    }


    }


    @available(iOS, deprecated: 15.0, obsoleted: 16.0,


    message: "Use `Text` with `AttributedString`")


    extension AttributedText {


    @resultBuilder


    enum Builder { ɾɾɾ }


    }

    View Slide

  42. var body: some View {


    VStack {


    if #available(iOS 15, *) {


    Text(attributedString)


    } else {


    AttributedText { // ←
    'AttributedText' is unavailable in iOS: Use
    `Text` with `AttributedString`


    Text("Foo")


    Text(" ")


    Text("Bar")


    .foregroundColor(.red)


    Text(" ")


    Text("Baz")


    .font(.title)


    Text(" ")


    Text("Qux")


    .font(.footnote)


    .foregroundColor(.green)


    Text(" ")


    Text("Quux")


    }


    }


    }


    }
    "UUSJCVUFE4USJOH
    PCTPMFUFEʹ͢ΔͱΤϥʔʹͳΔ
    @available(iOS, obsoleted: 15.0,


    message: "Use `Text` with `AttributedString`")


    struct AttributedText: View {


    typealias Body = Text


    var text: Text


    init(@Builder builder: () -> Text) {


    text = builder()


    }


    var body: Text {


    text


    }


    }


    @available(iOS, obsoleted: 15.0,


    message: "Use `Text` with `AttributedString`")


    extension AttributedText {


    @resultBuilder


    enum Builder { ɾɾɾ }


    }

    View Slide

  43. αϙʔτόʔδϣϯͷؔ܎Ͱ࢖͑ͳ͍"1*
    ˞J04ͷ"QQΛ૝ఆ
    w JGBWBJMBCMFΛ࢖ͬͯ
    w 8PSLBSPVOEͱซ༻͢Δ
    w ্ҐόʔδϣϯͷΈ࢖͑ΔΑ͏ʹ͢Δ
    w FY
    w "UUSJCVUFE4USJOH J04d

    w QSFTFOUBUJPO%FUFOUT J04d

    View Slide

  44. QSFTFOUBUJPO%FUFOUT
    struct ContentView: View {


    @State private var isPresenting = false


    var body: some View {


    VStack {


    Button {


    isPresenting = true


    } label: {


    VStack {


    Image(systemName: "globe")


    .imageScale(.large)


    Text("Hello, world!")


    }.foregroundColor(.accentColor)


    .padding()


    }


    .sheet(isPresented: $isPresenting) {


    SheetView()


    .presentationDetents([.medium]) // ← 'presentationDetents' is only available in iOS 16.0 or newer


    }


    }


    }


    }

    View Slide

  45. QSFTFOUBUJPO%FUFOUT
    struct ContentView: View {


    @State private var isPresenting = false


    var body: some View {


    VStack {


    Button {


    isPresenting = true


    } label: {


    VStack {


    Image(systemName: "globe")


    .imageScale(.large)


    Text("Hello, world!")


    }.foregroundColor(.accentColor)


    .padding()


    }


    .sheet(isPresented: $isPresenting) {


    if #available(iOS 16.0, *) {


    SheetView()


    .presentationDetents([.medium])


    } else {


    SheetView()


    }


    }


    }


    }


    }

    View Slide

  46. QSFTFOUBUJPO%FUFOUT
    GVODUJPOʹ੾Γग़͢
    extension View {


    @ViewBuilder


    func halfSheetIfAble(height: CGFloat? = nil) -> some View {


    if #available(iOS 16.0, *) {


    if let height {


    presentationDetents([.height(height)])


    } else {


    presentationDetents([.medium])


    }


    } else {


    self


    }


    }


    }


    struct ContentView: View {


    @State private var isPresenting = false


    var body: some View {


    VStack {


    Button {


    isPresenting = true


    } label: {


    VStack {


    Image(systemName: "globe")


    .imageScale(.large)


    Text("Hello, world!")


    }.foregroundColor(.accentColor)


    .padding()


    }


    .sheet(isPresented: $isPresenting) {


    SheetView()


    .halfSheetIfAble()


    }


    }


    }


    }


    View Slide

  47. QSFTFOUBUJPO%FUFOUT
    struct ContentView: View {


    @State private var isPresenting = false


    var body: some View {


    VStack {


    Button {


    isPresenting = true


    } label: {


    VStack {


    Image(systemName: "globe")


    .imageScale(.large)


    Text("Hello, world!")


    }.foregroundColor(.accentColor)


    .padding()


    }


    .sheet(isPresented: $isPresenting) {


    SheetView()


    .halfSheetIfAble()


    }


    }


    }


    }


    @available(iOS, deprecated: 16, message: "Use


    `presentationDetents` directly.")


    extension View {


    @ViewBuilder


    func halfSheetIfAble(height: CGFloat? = nil) -> some View {


    if #available(iOS 16.0, *) {


    if let height {


    presentationDetents([.height(height)])


    } else {


    presentationDetents([.medium])


    }


    } else {


    self


    }


    }


    }


    View Slide

  48. QSFTFOUBUJPO%FUFOUT
    .JOJNVN%FQMPZNFOU5BSHFUΛʹ͢Δͱܯࠂ͕ग़Δ
    struct ContentView: View {


    @State private var isPresenting = false


    var body: some View {


    VStack {


    Button {


    isPresenting = true


    } label: {


    VStack {


    Image(systemName: "globe")


    .imageScale(.large)


    Text("Hello, world!")


    }.foregroundColor(.accentColor)


    .padding()


    }


    .sheet(isPresented: $isPresenting) {


    SheetView()


    .halfSheetIfAble() // ←
    'halfSheetIfAble(height:)' was deprecated in iOS
    16: Use `presentationDetents` directly.


    }


    }


    }


    }


    @available(iOS, deprecated: 16, message: "Use


    `presentationDetents` directly.")


    extension View {


    @ViewBuilder


    func halfSheetIfAble(height: CGFloat? = nil) -> some View {


    if #available(iOS 16.0, *) {


    if let height {


    presentationDetents([.height(height)])


    } else {


    presentationDetents([.medium])


    }


    } else {


    self


    }


    }


    }


    View Slide

  49. QSFTFOUBUJPO%FUFOUT
    ผղಉ໊ͷCBDLQPSUGVODUJPOΛ༻ҙ͢Δ
    struct ContentView: View {


    @State private var isPresenting = false


    var body: some View {


    VStack {


    Button {


    isPresenting = true


    } label: {


    VStack {


    Image(systemName: "globe")


    .imageScale(.large)


    Text("Hello, world!")


    }.foregroundColor(.accentColor)


    .padding()


    }


    .sheet(isPresented: $isPresenting) {


    SheetView()


    .presentationDetents([.medium])


    }


    }


    }


    }
    @available(iOS, obsoleted: 16, message: "Use `presentationDetents` in SwiftUI
    directly.")


    extension View {


    @ViewBuilder


    func presentationDetents(_ detents: Set) -> some View {


    if #available(iOS 16.0, *) {


    presentationDetents(Set(detents.map(\.detent)))


    } else {


    self


    }


    }


    }


    /// Backporting for `SwiftUI.PresentationDetent`


    enum PresentationDetent: Hashable {


    ɾɾɾ


    }


    @available(iOS 16.0, *)


    extension PresentationDetent {


    var detent: SwiftUI.PresentationDetent {


    switch self {


    case .medium: return .medium


    ɾɾɾ


    }


    }


    }

    View Slide

  50. QSFTFOUBUJPO%FUFOUT
    .JOJNVN%FQMPZNFOU5BSHFUΛʹ͢ΔͱϏϧυΤϥʔ
    struct ContentView: View {


    @State private var isPresenting = false


    var body: some View {


    VStack {


    Button {


    isPresenting = true


    } label: {


    VStack {


    Image(systemName: "globe")


    .imageScale(.large)


    Text("Hello, world!")


    }.foregroundColor(.accentColor)


    .padding()


    }


    .sheet(isPresented: $isPresenting) {


    SheetView()


    .presentationDetents([.medium]) /
    / ← Ambiguous use of 'medium'


    }


    }


    }


    }
    @available(iOS, deprecated: 16, message: "Use `presentationDetents` in SwiftUI
    directly.")


    extension View {


    @ViewBuilder


    func presentationDetents(_ detents: Set) -> some View {


    if #available(iOS 16.0, *) {


    presentationDetents(Set(detents.map(\.detent)))


    } else {


    self


    }


    }


    }


    /// Backporting for `SwiftUI.PresentationDetent`


    enum PresentationDetent: Hashable {


    ɾɾɾ


    }


    @available(iOS 16.0, *)


    extension PresentationDetent {


    var detent: SwiftUI.PresentationDetent {


    switch self {


    case .medium: return .medium


    ɾɾɾ


    }


    }


    }

    View Slide

  51. QSFTFOUBUJPO%FUFOUT
    CBDLQPSUGVODUJPOΛফͤ͹ܯࠂ΋ফ͑Δ
    struct ContentView: View {


    @State private var isPresenting = false


    var body: some View {


    VStack {


    Button {


    isPresenting = true


    } label: {


    VStack {


    Image(systemName: "globe")


    .imageScale(.large)


    Text("Hello, world!")


    }.foregroundColor(.accentColor)


    .padding()


    }


    .sheet(isPresented: $isPresenting) {


    SheetView()


    .presentationDetents([.medium])


    }


    }


    }


    }
    //@available(iOS, obsoleted: 16, message: "Use `presentationDetents` in SwiftUI
    directly.")


    //extension View {


    // @ViewBuilder


    // func presentationDetents(_ detents: Set) -> some View {


    // if #available(iOS 16.0, *) {


    // presentationDetents(Set(detents.map(\.detent)))


    // } else {


    // self


    // }


    // }


    //}


    //


    ///// Backporting for `SwiftUI.PresentationDetent`


    //enum PresentationDetent: Hashable {


    // ɾɾɾ


    //}


    //


    //@available(iOS 16.0, *)


    //extension PresentationDetent {


    // var detent: SwiftUI.PresentationDetent {


    // switch self {


    // case .medium: return .medium


    // ɾɾɾ


    // }


    // }


    //}

    View Slide

  52. ·ͱΊ
    w BWBJMBCMFͱEFQSFDBUFEΛ࢖͏͜ͱͰӨڹൣғΛߜͬͨϦϑΝΫλϦϯά͕
    Մೳ
    w ͤʔͷͰ΍ΔΑΓ҆શ
    w ର৅͸ίϯύΠϥ͕ܯࠂΤϥʔʹͯ͘͠ΕΔͷͰQBTTJWFʹಈ͚Δ
    w SFNJOEFSతͳ໾ׂΛՌͨ͢
    w ݟམͱ͕͠ݮΔͷͰޮ཰61

    View Slide

  53. 'JO
    IUUQTHJUIVCDPN,*4XJGU"WBJMBCMF4BNQMF

    View Slide