Steven B.
Steven B.

Reputation: 1539

SwiftUI Share Button between iOS and TVOS, focusable(_:onFocusChange:)' is unavailable in iOS

I'm trying to share a (custom) SwiftUI Button on iOS and TVs platforms. I already notice the buttons look very different per platform but my main issue is ".focussable". For the button to show correctly in tvOS i need to add the focussable parameter tot he button. however when building the button for an iOS platform, i get the following error:

focusable(_:onFocusChange:)' is unavailable in iOS

Code:

Button(action: {}) {
        HStack {
            if let image = icon, let uiimage = UIImage(named: image) {
                Image(uiImage: uiimage)
            }
            if let title = label {
                Text(title)
            }
        }
    }
    .focusable(true) { focused in
        withAnimation {
            self.background(Color.purple)
        }
    }

How can I use focussable on this button and still keep it shared between iOS and tvOS?

Upvotes: 1

Views: 412

Answers (1)

Asperi
Asperi

Reputation: 257493

You need to use conditional compilation for such cases. For better reusability to is possible to wrap it in view modifier, like

struct DemoFocusableModifier: ViewModifier {
    private let isFocusable: Bool
    private let onFocusChange: (Bool) -> Void

    init (_ isFocusable: Bool = true, onFocusChange: @escaping (Bool) -> Void = { _ in }) {
        self.isFocusable = isFocusable
        self.onFocusChange = onFocusChange
    }

    @ViewBuilder
    func body(content: Content) -> some View {
#if os(tvOS)
        content
            .focusable(isFocusable, onFocusChange: onFocusChange)
#else
        content
#endif
    }
}

and use (instead of your .focusable) as

  }
  .modifier(DemoFocusableModifier { focused in
        // content here
  })

Prepared with Xcode 13 / iOS 15

Upvotes: 1

Related Questions