-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement customizable Flashcard view
- Loading branch information
1 parent
f66a83b
commit 9920b8f
Showing
5 changed files
with
196 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// | ||
// AnyTransition+Extension.swift | ||
// CardFlipster | ||
// | ||
// Created by Mariana Piz on 16.11.2024. | ||
// | ||
|
||
import SwiftUI | ||
|
||
// Code snippet sourced from Stack Overflow | ||
// https://stackoverflow.com/a/79162092 | ||
// Answer by Robert Dresler | ||
extension AnyTransition { | ||
|
||
@MainActor static func flip(side: FlipTransitionViewModifier.Side, | ||
axis: Axis = .horizontal, | ||
perspective: CGFloat = 0, | ||
animationDuration: TimeInterval = 0.25) -> AnyTransition { | ||
.modifier( | ||
active: FlipTransitionViewModifier( | ||
isActive: true, | ||
side: side, | ||
axis: axis, | ||
perspective: perspective | ||
), | ||
identity: FlipTransitionViewModifier( | ||
isActive: false, | ||
side: side, | ||
axis: axis, | ||
perspective: perspective | ||
) | ||
) | ||
.combined( | ||
with: .opacity.animation( | ||
.linear(duration: 0.001).delay(animationDuration / 2) | ||
) | ||
) | ||
.animation(.linear(duration: animationDuration)) | ||
} | ||
|
||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// | ||
// FlashcardView.swift | ||
// CardFlipster | ||
// | ||
// Created by Mariana Piz on 15.11.2024. | ||
// | ||
|
||
import SwiftUI | ||
|
||
public struct FlashcardView: View { | ||
|
||
private enum Constants { | ||
static let cardWidth: CGFloat = 300 | ||
static let cardHeight: CGFloat = 450 | ||
static let cornerRadius: CGFloat = 10 | ||
static let minScaleFactor: CGFloat = 0.8 | ||
} | ||
|
||
@State private var side: FlipTransitionViewModifier.Side = .front | ||
|
||
private var frontText: String = "Front" | ||
private var backText: String = "Back" | ||
private var frontColor: Color = .blue | ||
private var backColor: Color = .yellow | ||
private var font: Font = .title | ||
private var frontFontColor: Color = .white | ||
private var backFontColor: Color = .black | ||
private var axis: Axis = .horizontal | ||
private var animationDuration: TimeInterval = 0.6 | ||
|
||
public init( | ||
frontText: String = "Front", | ||
backText: String = "Back", | ||
frontColor: Color = .blue, | ||
backColor: Color = .yellow, | ||
font: Font = .title, | ||
frontFontColor: Color = .white, | ||
backFontColor: Color = .black, | ||
axis: Axis = .horizontal, | ||
animationDuration: TimeInterval = 0.6 | ||
) { | ||
self.frontText = frontText | ||
self.backText = backText | ||
self.frontColor = frontColor | ||
self.backColor = backColor | ||
self.font = font | ||
self.frontFontColor = frontFontColor | ||
self.backFontColor = backFontColor | ||
self.axis = axis | ||
self.animationDuration = animationDuration | ||
} | ||
|
||
public var body: some View { | ||
VStack { | ||
cardView | ||
} | ||
} | ||
|
||
private var cardView: some View { | ||
flashcard | ||
.id(side) | ||
.transition(.flip(side: side, | ||
axis: axis, | ||
animationDuration: animationDuration)) | ||
.onTapGesture { | ||
withAnimation(.easeInOut(duration: animationDuration)) { | ||
side = side == .front ? .back : .front | ||
} | ||
} | ||
} | ||
|
||
private var flashcard: some View { | ||
RoundedRectangle(cornerRadius: Constants.cornerRadius) | ||
.fill(side == .back ? backColor : frontColor) | ||
.overlay(contentOverlay) | ||
.frame(width: Constants.cardWidth, height: Constants.cardHeight) | ||
} | ||
|
||
private var contentOverlay: some View { | ||
Text(side == .front ? frontText : backText) | ||
.font(font) | ||
.foregroundColor(side == .front ? frontFontColor : backFontColor) | ||
.padding() | ||
.minimumScaleFactor(Constants.minScaleFactor) | ||
} | ||
} | ||
|
||
#Preview { | ||
FlashcardView( | ||
frontText: "Hello, World!", | ||
backText: "Goodbye, World!", | ||
frontColor: .blue, | ||
backColor: .yellow, | ||
font: .largeTitle, | ||
frontFontColor: .white, | ||
backFontColor: .black, | ||
axis: .horizontal, | ||
animationDuration: 0.8 | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// | ||
// FlipTransitionViewModifier.swift | ||
// CardFlipster | ||
// | ||
// Created by Mariana Piz on 16.11.2024. | ||
// | ||
|
||
import SwiftUI | ||
|
||
// Code snippet sourced from Stack Overflow | ||
// https://stackoverflow.com/a/79162092 | ||
// Answer by Robert Dresler | ||
struct FlipTransitionViewModifier: ViewModifier { | ||
|
||
public enum Side { | ||
case front | ||
case back | ||
} | ||
|
||
let isActive: Bool | ||
let side: Side | ||
let axis: Axis | ||
let perspective: CGFloat | ||
|
||
public func body(content: Content) -> some View { | ||
content | ||
.rotation3DEffect( | ||
Angle.degrees(side == .back ? 0 : 180), | ||
axis: resolvedAxis, | ||
perspective: 0 | ||
) | ||
.rotation3DEffect( | ||
Angle.degrees( | ||
isActive | ||
? (side == .back ? 180 : 0) | ||
: (side == .back ? 0 : 180) | ||
), | ||
axis: resolvedAxis, | ||
perspective: perspective | ||
) | ||
} | ||
|
||
private var resolvedAxis: (CGFloat, CGFloat, CGFloat) { | ||
switch axis { | ||
case .horizontal: | ||
(0, 1, 0) | ||
case .vertical: | ||
(1, 0, 0) | ||
} | ||
} | ||
|
||
} |