mekhi brodie
mekhi brodie

Reputation: 15

How to recreate the journal app UI animation?

I'm making a journal-esque app and taking some design references from Apple's stock journal app. The animation that happens when you expand the text on a journal entry seems impossible to do so smoothly in just swiftui. I've linked my code below. The code produces jittery animations and looks unpolished. Any pointers or help would be greatly appreciated!

import SwiftUI
struct CardView: View {
    
    var text: String
    var cardIcon: Text
    @Binding var isExpanded: Bool
    @State private var height: CGFloat = 250 // add this to modify
                                             // the height of the Rounded Rectangle
    let expandedHeight: CGFloat = 650
    
    
    var body: some View {
                    VStack(alignment: .leading, spacing: 0) {
                        icon
                        zodiacText()
                    }.background {
                        outerBackground().overlay {
                        innerBackground()
                        }
                    }.frame(maxHeight: height).animation(.default, value: isExpanded).clipped().fixedSize(horizontal: false, vertical: true)
            .onTapGesture {
                   withAnimation(.easeInOut) { // Smooth transition
                       isExpanded.toggle() // Toggle the expanded state
                       height = isExpanded ? expandedHeight : 250 // Update height based on expansion
                   }
               }
               .onChange(of: isExpanded) { newValue in
                   withAnimation(.easeInOut) { // Smooth transition on state change
                       height = newValue ? expandedHeight : 250 // Adjust height accordingly
                   }
               }
    }
    
    var icon: some View {
        ZStack {
            Circle().frame(width: isExpanded ? CardIconConstants.expandedCircleFrameWidth : CardIconConstants.circleFrameWidth).foregroundStyle(Color.white).overlay {
                cardIcon.font(isExpanded ? .title : .callout)
            }
            
        }.clipped().padding().padding([.trailing, .leading, .top]).clipped().scaleEffect(1)
    }
    
    func outerBackground() -> some View {
        RoundedRectangle(cornerRadius: CardIconConstants.cornerRadius)
            .foregroundStyle(.ultraThickMaterial)
        
    }
    
    func innerBackground() -> some View {
        RoundedRectangle(cornerRadius: CardIconConstants.cornerRadius).padding([.trailing, .top, .bottom, .leading]).foregroundStyle(Color.black)
    }
    
    func zodiacText() -> some View {
        Text(text).foregroundStyle(Color.white).fontWeight(.semibold).padding([.leading, .trailing, .bottom]).padding([.leading, .trailing, .bottom])
    }
    
    private struct CardIconConstants {
        static var cornerRadius = 15.0
        static var clearBackgroundWidthMuliplier = 0.5
        static var clearBackgroundHeightDivider = 3.0
        static var lineLimit: Int = 4
        static var circleFrameWidth: CGFloat = 30
        static var expandedCircleFrameWidth: CGFloat = 50
        static var innerBGframeWidthDivider = 1.0
    }
}

Upvotes: 0

Views: 54

Answers (0)

Related Questions