Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting fraction programmatically (after the split view is shown already) #29

Closed
objecthub opened this issue Oct 28, 2023 · 2 comments · Fixed by #32
Closed

Setting fraction programmatically (after the split view is shown already) #29

objecthub opened this issue Oct 28, 2023 · 2 comments · Fixed by #32

Comments

@objecthub
Copy link

objecthub commented Oct 28, 2023

I couldn't figure out a way how to set the split fraction between primary and secondary view programmatically (e.g. by manipulating the FractionHolder). To me it looks like the fraction holder gets updated after the drag is over, but any changes to the value of the fraction holder are not propagated into the view. I'd like to provide a button that resets the split fraction to 0.5. Am I right in assuming that this is currently not possible?

@stevengharris
Copy link
Owner

stevengharris commented Oct 28, 2023

I was surprised to find that this is currently not possible. For one thing, I didn't publish the value of FractionHolder. Ugh. Doing that seems harmless:

public class FractionHolder: ObservableObject {
    @Published public var value: CGFloat {
        didSet {
            setter?(value)
        }
    }

If you do that, then you can monitor changes in Split on the ZStack:

    .onChange(of: fraction.value) { new in constrainedFraction = new }  // <- new line 102

This will trigger when fraction is set at the end of drag, but that won't matter, since new will be the constrainedFraction at the end of drag. Now if you change the state of the FractionHolder, the Split view will update. I will probably double-check all this later and incorporate the changes, but this should do the trick for now. The added onChange here in Split only will work for HSplit and VSplit, too (i.e., they don't need to be modified). Here's what I used to test:

struct FractionTestView: View {
    @State private var fraction = FractionHolder(0.25)
    var body: some View {
        VStack {
            Button(action: { fraction.value = 0.5 }, label: { Text("Restore to middle") })
            HSplit(left: {Color.red}, right: {Color.green})
                .fraction(fraction)
        }
    }
}

@objecthub
Copy link
Author

objecthub commented Oct 30, 2023

Thanks for your response and for identifying a solution! In your new line 102, you might also have to check for the fraction constraints to make sure that internal invariants aren't broken by a fraction provided from outside that is not valid.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants