Swift UI에서 전환 애니메이션이 제대로 작동하지 않음
버튼을 눌러 화면 중앙에 메시지를 표시/숨기는 매우 간단한 전환 애니메이션을 만들려고 합니다.
struct ContentView: View {
@State private var showMessage = false
var body: some View {
ZStack {
Color.yellow
VStack {
Spacer()
Button(action: {
withAnimation(.easeOut(duration: 3)) {
self.showMessage.toggle()
}
}) {
Text("SHOW MESSAGE")
}
}
if showMessage {
Text("HELLO WORLD!")
.transition(.opacity)
}
}
}
}
의 문서에 따르면..transition(.opacity)
애니매이션
삽입 시 투명에서 불투명으로 전환되고 제거 시 불투명에서 투명으로 전환됩니다.
메시지는 다음과 같이 사라져야 합니다.showMessage
상태 속성이 true가 되고 false가 되면 페이드아웃됩니다.이것은 제 경우에는 사실이 아닙니다.메시지는 페이드 애니메이션과 함께 표시되지만 애니메이션이 전혀 없는 상태로 숨습니다.아이디어 있어요?
편집: 다음에서 결과를 확인합니다.gif
아래는 시뮬레이터에서 찍은 것입니다.
문제는 ZStack에서 뷰가 오고 갈 때 "zIndex"가 그대로 유지되지 않는다는 것입니다.이 경우 "showMessage"가 true에서 false로 변경되면 "Hello World" 텍스트가 포함된 VStack이 스택의 맨 아래에 배치되고 그 위에 노란색이 즉시 그려집니다.실제로 색이 바래고 있는데 노란색 뒤에서 색이 바래서 보이지 않습니다.
이 문제를 해결하려면 스택의 각 보기에 대해 "zIndex"를 명시적으로 지정하여 항상 동일하게 유지해야 합니다.
struct ContentView: View {
@State private var showMessage = false
var body: some View {
ZStack {
Color.yellow.zIndex(0)
VStack {
Spacer()
Button(action: {
withAnimation(.easeOut(duration: 3)) {
self.showMessage.toggle()
}
}) {
Text("SHOW MESSAGE")
}
}.zIndex(1)
if showMessage {
Text("HELLO WORLD!")
.transition(.opacity)
.zIndex(2)
}
}
}
}
제 연구 결과는 불투명도 전환이 항상 효과적인 것은 아니라는 것입니다.(슬라이드와 .slide를 함께 사용하면 작동합니다.)
.transition(.opacity) //does not always work
사용자 지정 애니메이션으로 작성하면 작동합니다.
.transition(AnyTransition.opacity.animation(.easeInOut(duration: 0.2)))
.zIndex(1)
나는 swift에서 벌레를 발견했습니다.애니메이션을 위한 UI_미리보기.코드에서 전환 애니메이션을 사용하고 스위프트에서 해당 애니메이션을 보고 싶을 때UI_preview는 애니메이션을 표시하지 않거나 애니메이션과 함께 일부 보기가 사라질 때만 표시됩니다.이 문제를 해결하려면 VStack에서 미리 보기를 추가하기만 하면 됩니다.이런 식으로:
struct test_UI: View {
@State var isShowSideBar = false
var body: some View {
ZStack {
Button("ShowMenu") {
withAnimation {
isShowSideBar.toggle()
}
}
if isShowSideBar {
SideBarView()
.transition(.slide)
}
}
}
}
struct SomeView_Previews: PreviewProvider {
static var previews: some View {
VStack {
SomeView()
}
}
}
이것 이후에, 모든 애니메이션이 일어날 것입니다.
저는 이것이 캔버스의 문제라고 생각합니다.오늘 아침에 전환 작업을 하고 있었는데 캔버스에서 작동하지 않는 동안 시뮬레이터에서 작동하는 것 같습니다.한번 시도해 보세요.저는 애플에 버그를 보고했습니다.
Scott Gribben의 답변(아래 참조)이 더 마음에 들지만, (녹색 체크로 인해) 이 답변을 삭제할 수 없기 때문에 원래 답변은 그대로 두겠습니다.하지만 저는 그것을 벌레라고 생각한다고 주장할 것입니다.코드에 나타나는 순서 보기에 의해 zIndex가 암시적으로 할당될 것으로 예상할 수 있습니다.
이 문제를 해결하기 위해 VStack 내부에 if 문을 포함시킬 수 있습니다.
struct ContentView: View {
@State private var showMessage = false
var body: some View {
ZStack {
Color.yellow
VStack {
Spacer()
Button(action: {
withAnimation(.easeOut(duration: 3)) {
self.showMessage.toggle()
}
}) {
Text("SHOW MESSAGE")
}
}
VStack {
if showMessage {
Text("HELLO WORLD!")
.transition(.opacity)
}
}
}
}
}
zIndex
중단 시 애니메이션이 중단될 수 있습니다.▁a▁you▁view로 감습니다.VStack
,HStack
아니면 다른 용기가 말이 될 것입니다.
저는 그냥 .transition을 포기했습니다.작동이 안 돼요.대신 보기의 오프셋을 애니메이션화하여 훨씬 더 신뢰할 수 있도록 했습니다.
먼저 오프셋에 대한 상태 변수를 만듭니다.
@State private var offset: CGFloat = 200
두 번째로 VStack의 오프셋을 설정했습니다.그런 다음 .onApear()의 .onApear()에서 애니메이션을 사용하여 오프셋을 0으로 다시 변경합니다.
VStack{
Spacer()
HStack{
Spacer()
Image("MyImage")
}
}
.offset(x: offset)
.onAppear {
withAnimation(.easeOut(duration: 2.5)) {
offset = 0
}
}
아래 코드가 작동해야 합니다.
import SwiftUI
struct SwiftUITest: View {
@State private var isAnimated:Bool = false
var body: some View {
ZStack(alignment:.bottom) {
VStack{
Spacer()
Button("Slide View"){
withAnimation(.easeInOut) {
isAnimated.toggle()
}
}
Spacer()
Spacer()
}
if isAnimated {
RoundedRectangle(cornerRadius: 16).frame(height: UIScreen.main.bounds.height/2)
.transition(.slide)
}
}.ignoresSafeArea()
}
}
struct SwiftUITest_Previews: PreviewProvider {
static var previews: some View {
VStack {
SwiftUITest()
}
}
}
당신은 그것을.
.id(showMessage)
V 스택의 본체 이후에, 그것은 당신을 도울 것입니다.
SwiftUI 사용자 지정 불투명도 전환
다음을 위해 연장할 수 있습니다.in
그리고.out
불투명 전환.
import SwiftUI
extension AnyTransition {
static var inOpacity: AnyTransition {
AnyTransition.modifier(
active: OpacityModifier(opacity: 0),
identity: OpacityModifier(opacity: 1)
)
}
static var outOpacity: AnyTransition {
AnyTransition.modifier(
active: OpacityModifier(opacity: 1),
identity: OpacityModifier(opacity: 0)
)
}
}
struct OpacityModifier : ViewModifier {
let opacity: Double
func body(content: Content) -> some View {
content.opacity(opacity)
}
}
struct ContentView : View {
@State var isMessageVisible: Bool = false
@State var text = Text("SwiftUI Transition Animation")
.font(.largeTitle)
.foregroundColor(.yellow)
var body: some View {
ZStack {
Color.indigo.ignoresSafeArea()
VStack {
Spacer()
Button("SHOW MY MESSAGE") {
withAnimation(.linear(duration: 2)) {
isMessageVisible.toggle()
}
}
}
if isMessageVisible {
text.transition(.inOpacity) // in
} else {
text.transition(.outOpacity) // out
}
}
}
}
언급URL : https://stackoverflow.com/questions/57730074/transition-animation-not-working-properly-in-swiftui
'programing' 카테고리의 다른 글
시스템.Linq.IQueryable에 '위치'에 대한 정의가 없습니다. (0) | 2023.08.08 |
---|---|
ORM을 통해 SQLAlchemy 개체를 로드하는 것이 원시 MySQLDB 커서를 통해 행을 로드하는 것보다 느린 이유는 무엇입니까? (0) | 2023.08.08 |
안드로이드에서 카운트다운 타이머를 만드는 방법은? (0) | 2023.08.08 |
Swift에서 원시 값에서 열거형을 가져오는 방법은 무엇입니까? (0) | 2023.08.08 |
페이스북 아이폰 앱에서 지원하는 모든 사용자 지정 URL 체계는 무엇입니까? (0) | 2023.08.08 |