0
votes

I'm building an iOS app and currently I've found a strange behaviour with Divider component.

See the following screenshot:

enter image description here

The chevron on the top right side makes the other two(or more) components appear/disappear, the problem happens with the vertical Divider which should appear next to CONTROLS A.

The general SwiftUI hierarchy for the view is something similar to ScrollView -> VStack -> ForEach -> [HStack -> Img Divider VStack (with SOME TEXT + CONTROLS X)].

Note that it happens not only for the first component. Controls X contains SwiftUI components, nothing custom.

Now some interesting facts I've found after debugging:

  • If I make the Divider show/disappear with a boolean flag which changes on tap, the Divider is shown as expected
  • If I make the Divider show/disappear with a boolean flag which changes on "onAppear" the Divider is not shown
  • The Divider view is included with width 0.33 but height 0 (that's the real problem)
  • Adding or removing views to "Controls A" can make the Divider show

Been trying to find the cause for it without success so I'm inclined to think it's probably a bug where the final height is not properly updated for the Divider component.

Update: The issue happens only on some devices, iPhone 12 is one of them.

Here's some code to reproduce a similar issue (in this case the divider is visible but its height is wrong):

struct BugScreen: View {
    var body: some View {
        VStack {
            Text("Bug Test")
            ScrollView(showsIndicators: false) {
                ForEach((1..<3)) { i in
                    MyView(index:i)
                }
                Spacer(minLength: 75)
            }
            .padding(.horizontal, 20)
        }
        .navigationBarTitle("", displayMode: .inline)
    }
}

struct MyView: View {
    @State var expanded = false
    var index: Int
    
    var body: some View {
        VStack(spacing: 0) {
            HStack(spacing: 15) {
                Image("ImageName")
                    .resizable()
                    .frame(width: 50, height: 50)
                Divider()
                VStack(alignment: .leading) {
                    VStack(alignment: .leading, spacing: 5) {
                        HStack {
                            Text("Test \(index)")
                                .font(.headline)
                                .fontWeight(.light)
                                .fixedSize(horizontal: false, vertical: true)
                            Spacer()
                            
                            Image(systemName: expanded ? "chevron.up": "chevron.down")
                                .padding(.leading, 10)
                                .font(Font.body.weight(.thin))
                        }
                    }
                    
                    Divider()
                    
                    Text("Some text")
                            .fixedSize(horizontal: false, vertical: true)
                    
                }
            }
            .padding([.vertical, .leading])
            .padding(.trailing, 5)
            .background(
                RoundedRectangle(cornerRadius: expanded ? 0: 25, style: .continuous).foregroundColor(.white)
            )
            .onTapGesture {
                    withAnimation { expanded.toggle() }
            }
            
            if expanded {
                Divider().background(Color(.black))
                VStack {
                    ForEach((1..<4)) { control in
                            Spacer(minLength: 10)
                            MyControlsView()
                            Divider().background(Color(.black))
                        
                    }
                    Text("More text")
                }
                .padding(.horizontal, 10)
                .background(Color.white)
            }
            
            Divider().background(Color(.black))
        }
    }

struct MyControlsView: View {
    @State var sliderValue = 0.0
    var body: some View {
        VStack {
            HStack {
                Image("image_name")
                    .resizable()
                    .frame(width: 50, height: 50, alignment: .center)
                
                Divider()
                
                VStack(alignment: .leading) {
                    Text("My controls")
                    
                    Divider()

                    VStack(alignment: .leading) {
                        Slider(value: $sliderValue, in: 0...100)
                        Slider(value: $sliderValue, in: 0...100)
                        Slider(value: $sliderValue, in: 0...100)
                        Text("Hello")
                        Text("Some other text")
                    }
                    .disabled(false)
                    .padding(0)
                    .background(
                        RoundedRectangle(cornerRadius: 10, style: .continuous)
                            .foregroundColor(
                                .clear
                            )
                    )
                }
            }
        }
        .accentColor(.black)
        .padding()
    }   
}
1
Would you add problem code example and point what do you expect in it? - Asperi
Sure, updated with a code sample and specified that the error happens only on some devices - PizergSensing

1 Answers

0
votes

Found the way to make it behave as expected, just had to add .fixedSize(horizontal: false, vertical: true)