最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

swift - How to support optional binding in a view? - Stack Overflow

programmeradmin0浏览0评论

I want to pass a nullable binding to the view.

public struct Accordion<Trigger, Content>: View where Trigger: View, Content: View {
    let trigger: Trigger
    let content: Content

    @State private var isExpanded = false

    // TODO: PASS isExpanded AS A OPTIONAL BINDING FROM OUTSIDE
    public init(@ViewBuilder trigger: () -> Trigger, @ViewBuilder content: () -> Content) {
        self.trigger = trigger()
        self.content = content()
    }

    public var body: some View {
        ZStack {
            VStack(spacing: 0.0) {
                triggerWrappedView
                    .onTapGesture {
                        isExpanded.toggle()
                    }

                content
            }
        }
    }
}

In the view initalizer if we passed a binding use that else somehow create your own binding.

I want to pass a nullable binding to the view.

public struct Accordion<Trigger, Content>: View where Trigger: View, Content: View {
    let trigger: Trigger
    let content: Content

    @State private var isExpanded = false

    // TODO: PASS isExpanded AS A OPTIONAL BINDING FROM OUTSIDE
    public init(@ViewBuilder trigger: () -> Trigger, @ViewBuilder content: () -> Content) {
        self.trigger = trigger()
        self.content = content()
    }

    public var body: some View {
        ZStack {
            VStack(spacing: 0.0) {
                triggerWrappedView
                    .onTapGesture {
                        isExpanded.toggle()
                    }

                content
            }
        }
    }
}

In the view initalizer if we passed a binding use that else somehow create your own binding.

Share Improve this question asked Mar 29 at 16:46 Kunal KambleKunal Kamble 1381 silver badge6 bronze badges 3
  • What's wrong with @Binding here? – sonle Commented Mar 29 at 17:23
  • 1 See if this answer helps, which shows an optional binding: var selection: Binding<Int>? = nil – Andrei G. Commented Mar 30 at 0:47
  • If you doesn't use isExpanded in view body, then better just add handler of onTapGesture – Cy-4AH Commented Mar 31 at 9:28
Add a comment  | 

1 Answer 1

Reset to default 2

If Accordion only needs to write (toggle) to the binding, you can just replace the isExpanded state with:

let isExpanded: Binding<Bool>?

Initialise it in the initialiser:

public init(isExpanded: Binding<Bool>? = nil, @ViewBuilder trigger: () -> Trigger, @ViewBuilder content: () -> Content) {
    self.isExpanded = isExpanded
    self.trigger = trigger()
    self.content = content()
}

Then use optional chaining when toggling it:

.onTapGesture {
    isExpanded?.wrappedValue.toggle()
}

Note that isExpanded is not a property wrapped in @Binding. It is of type Binding<Bool>?, so you need to access wrappedValue to access the binding's value.


If Accordion needs to keep track of the isExpanded state even if the caller did not pass in a binding to its initialiser, you should keep the @State, in addition to the extra Binding<Bool>? property. See this post for more info.

发布评论

评论列表(0)

  1. 暂无评论