Peter F.
Peter F.

Reputation: 246

How to create two text views that are the same size

I am working on a game and I have text views representing cards that can be flipped. There is text on each side of the card. I would like the card to be the same size on each side. i.e. I would like the card on the side with less text to be the same size as the card on the size with more text. I don't want to hard code the card size as sometimes there will be only one line of text and other times there will be multiple lines of text. Here is an excerpt of the code I currently have:

import SwiftUI

struct FlipTestView: View {
    
    @State var flipped = false
    
    var body: some View {
        let flipDegrees = flipped ? 180.0 : 0
        VStack {
            ZStack() {
                Text("Card One First Side Of Card")
                    .placedOnCard(Color.yellow)
                    .flipRotate(flipDegrees).opacity(flipped ? 0.0 : 1.0)
                Text("""
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
                    """)
                    .placedOnCard(Color.green)
                    .flipRotate(-180 + flipDegrees).opacity(flipped ? 1.0 : 0.0)
            }
            .animation(.easeInOut(duration: 0.8))
            .onTapGesture { flipped.toggle()}
        }
    }
}

struct FlipTestView_Previews: PreviewProvider {
    static var previews: some View {
        FlipTestView()
    }
}

extension View {
    
    func flipRotate(_ degrees : Double) -> some View {
        return rotation3DEffect(Angle(degrees: degrees), axis: (x: 1.0, y: 0.0, z: 0.0))
    }
    
    func placedOnCard(_ color: Color) -> some View {
        return
            padding(15)
            //            .frame(width: 350, height: 65, alignment: .center).background(color)
            .background(color)
            .cornerRadius(16)
            .overlay(
                RoundedRectangle(cornerRadius: 16)
                    .stroke(Color.blue, lineWidth: 4)
            )
    }
}

Upvotes: 1

Views: 151

Answers (1)

vacawama
vacawama

Reputation: 154513

Move the .placedOnCard to the ZStack that contains both sides, then it will be sized to the larger of the two sides. Here is a solution that refactors your code:

ZStack() {
    Text("Card One First Side Of Card")
        .opacity(flipped ? 0.0 : 1.0)
    Text("""
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
        """)
        .flipRotate(180.0).opacity(flipped ? 1.0 : 0.0)
}
.placedOnCard(flipped ? Color.green : Color.yellow)
.flipRotate(flipDegrees)
.animation(.easeInOut(duration: 0.8))
.onTapGesture { flipped.toggle()}

demo of card flip in simulator

Upvotes: 2

Related Questions