Scott Andrew
Scott Andrew

Reputation: 81

SwiftUI: Transition won't slide

I have control with an edit and a list in a Stack. I want the list to drop down from top to bottom to animate like a fancy menu. However I am having a few issues. If I just try to use the move transition nothing happens. If I use the scale transition it always scales form center never from top down. This was just trying to get the transition overridden to slide. Anything but fade.

My control looks like so

struct Search: Identifiable {
    let id: UUID
    let text: String
}

struct SearchBox: View {
    @State var searchParam: String = ""
    @State var stuff = [Search]()

    init() {
        // To remove only extra separators below the list:
        UITableView.appearance().tableFooterView = UIView()

        // To remove all separators including the actual ones:
        UITableView.appearance().separatorStyle = .none
    }

    var body: some View {
        var binding = Binding<String>(
        get: {
            self.searchParam
        },
        set: {
            self.stuff.append(
                Search(id: UUID(), text: $0))
                self.searchParam = $0
        })

        return VStack(spacing: 0.0) {
            TextField("Search", text: binding )
                .font(.title)
                .padding()
                .background(Color.white)

            Color(.darkGray)
                .frame(height: 1.0)

            if stuff.count > 0 {
                List(stuff, id: \.id) {
                    Text($0.text)
                }
                .transition(.slide)
            }
        }
    }

    struct SearchBox_Preview: PreviewProvider {
        static var previews: some View{
            SearchBox()
        }
    }
}

The content view is simple..

struct ContentView: View {
    var body: some View {
        GeometryReader { geometry in
        ZStack(alignment: .topLeading) {
            Color.blue
              SearchBox()
                    .frame(width: geometry.size.width * 0.40, alignment: .topLeading)
                    .frame(minHeight: 0, maxHeight: geometry.size.height * 0.40,
                           alignment: .topLeading)
            .padding()
            .clipped()
                .shadow(radius: 5.0)
        }
        .background(Color.clear)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

I have to be missing, or not getting, something simple

Upvotes: 0

Views: 1773

Answers (1)

Scott Andrew
Scott Andrew

Reputation: 91

Answered my own question. We need to force an animation by using withAnimation on a state. So I have changed my biding to be like so:

struct Search: Identifiable {
    let id: UUID
    let text: String
}

struct SearchBox: View {
    @State var searchParam: String = ""
    @State var stuff = [Search]()
    @State var showList = false

    init() {
        // To remove only extra separators below the list:
        UITableView.appearance().tableFooterView = UIView()

        // To remove all separators including the actual ones:
        UITableView.appearance().separatorStyle = .none
    }

    var body: some View {
        var binding = Binding<String>(
        get: {
            self.searchParam
        },
        set: {
            self.stuff.append(
                Search(id: UUID(), text: $0)
            )
            self.searchParam = $0

            // change visibility state with in animation block.
            withAnimation { self.showList = stuff.count > 0 }
        })

        return VStack(spacing: 0.0) {
            TextField("Search", text: binding )
                .font(.title)
                .padding()
                .background(Color.white)

            Color(.darkGray)
                .frame(height: 1.0)

            if showList {
                List(stuff, id: \.id) {
                    Text($0.text)
                }
                .transition(.slide)
            }
        }
    }

    struct SearchBox_Preview: PreviewProvider {
        static var previews: some View{
            SearchBox()
        }
    }
}

Upvotes: 2

Related Questions