SwiftUI - анимация нового изображения внутри текущего представления - PullRequest
0 голосов
/ 04 апреля 2020

У меня есть представление, в котором я использую подпредставление «Изображение (изображение)» для отображения изображения, которое может иметь различные форматы высоты и ширины.

Ссылка на изображение извлекается из массива, что позволяет мне отображать различные изображения в моем представлении, изменяя ссылку. SwiftUI упорядочить содержимое представления для каждого нового изображения

Мне нужна анимация на этом изображении, скажем эффект масштаба, когда изображение отображается

1) Мне нужна первая .animation ( ноль), чтобы избежать анимации прежнего изображения (в противном случае у меня появляется ужасное затухание и деформация пропорций). Кажется, исправление

2) Но тогда у меня есть проблема с модификатором scaleEffect (даже если я установил его в scale = 1, где он ничего не должен делать). Анимация перемещается от изображения 1 к изображению 2 путем наложения что верхний левый угол изображения 2 начинается с позиции верхнего левого угла изображения 1, что при различной ширине и высоте провоцирует нежелательный перевод центра изображения
Это воспроизводится в приведенном ниже коде, где для демонстрационных целей Я использую системные образы (которые не подвержены ошибкам 1))

Как этого избежать?

3) В демонстрационном коде ниже я запускаю новое изображение кнопкой , что позволяет мне использовать действие и обрабатывать «масштабную» модификацию и явно достигать желаемого эффекта. Однако в моем реальном коде изменение изображения вызвано другим изменением в другом представлении.

Свифт знает, что, следовательно, я могу использовать неявный модификатор .animation.

Однако я не могу понять, как навязать сброс «масштаба» для любого нового изображения и выполнить мой желаемый эффект.

  • Если я использую onAppear (мой код), он работает только для первого отображаемого изображения, а не для следующих.

  • В реальном коде у меня есть представление Picture (изображение), а Picture (image.animation ()) не компилируется.

Любая идея о том, как выполнить действие, приведенную ниже код в кнопке на неявную анимацию?

спасибо

import SwiftUI

let portrait = Image(systemName: "square.fill")
let landscape = Image(systemName: "square.fill")

struct ContentView: View {
    @State var modified = false
    @State var scale: CGFloat = 1

var body: some View {
    return VStack(alignment: .center) {

        Pictureclip(bool: $modified)  
            .animation(nil)
            .scaleEffect(scale)
            .animation(.easeInOut(duration: 1))

       Button(action: {
        self.modified.toggle()
        self.scale = 1.1
        DispatchQueue.main.asyncAfter(deadline: .now() + 1)
            {self.scale = 1}
        }) {
            Text("Tap here")
                .animation(.linear)
        }            
     }
}
}
struct Pictureclip: View {

  @Binding var bool: Bool

  var body: some View {
  if bool == true {
    return  portrait
        .resizable()
        .frame(width: 100, height: 150)
        .foregroundColor(.green)
  } else {
   return  landscape
        .resizable()
        .frame(width: 150, height: 100)
        .foregroundColor(.red)
    }
    }
}

1 Ответ

0 голосов
/ 07 апреля 2020

У меня есть полуответ на мой вопрос, а именно пункты 1 и 2 (здесь со ссылкой на два изображения в формате JPEG в каталоге активов)

import SwiftUI
let portrait = Image("head")
let landscape = Image("sea")

struct ContentView: View {
    @State var modified = false
    @State var scale: CGFloat = 0.95


var body: some View {
    VStack(){

    GeometryReader { geo in
        VStack {
            Picture(bool: self.modified)
                .frame(width: geo.size.width * self.scale)
        }
        }
      Spacer()
      Button(action: {
                self.scale = 0.95
                self.modified.toggle()

        withAnimation(.easeInOut(duration: 0.5)){
                    self.scale = 1

                }
      }) {
                Text("Tap here")
          }
    }
}
}
struct Picture: View {
    var bool: Bool
var body: some View {
if bool == true {
    return  portrait
        .resizable().aspectRatio(contentMode: .fit)
        .padding(.all,6.0)
} else {
   return  landscape
        .resizable().aspectRatio(contentMode: .fit)
        .padding(.all,6.0)
}
}
}

Это решение позволяет масштабировать без искажения соотношения сторон изображения. новое изображение во время анимации. Но это не работает в коде, где обновление изображения запускается в другом представлении. Я предполагаю, что мне нужно реструктурировать свой код, чтобы решить мою проблему или представить ее более четко.

Редактировать: быстрое и грязное решение состоит в том, чтобы поместить код запуска (здесь код действия в кнопке) в другое представление. А именно, поместите в представление B код, который анимирует представление A, с переменной состояния, переданной ему (здесь, «scale»). Я уверен, что есть более чистые способы, но по крайней мере это работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...