Почему не работает анимация?


#1

Почему не работает анимация? Пробовал все закоментированные варианты. Не чего не получилось.

import SwiftUI

struct ContentView: View {

var width = UIScreen . main . bounds . width

var height = UIScreen . main . bounds . height

var coefficientShape = UIScreen . main . bounds . width/ UIScreen . main . bounds . height

@ State var isPortrait : Bool = true

@ State var progress : Double = 0.0

@ State var temperature : Double = 0.0

var body : some View {

VStack {

Path {path in

path. move (to: CGPoint (x: isPortrait ? width ***** 0.53 : height ***** 0.52, y: isPortrait ? ( height ***** 0.25 - 0.25 ***** height ***** CGFloat (self. progress ) ***** CGFloat ( coefficientShape ) - 20) : ( width ***** (0.25 - 0.25 ***** CGFloat (self. progress ) ***** CGFloat ( coefficientShape )))))

path. addLine (to: CGPoint (x: isPortrait ? width ***** 0.57 : height ***** 0.54, y: isPortrait ? (0.25 ***** height - 0.25 ***** height ***** CGFloat (self. progress ) ***** CGFloat ( coefficientShape ) - 16) : ( width ***** (0.25 - 0.25 ***** CGFloat (self. progress ) ***** CGFloat ( coefficientShape )) + 5)))

path. addLine (to: CGPoint (x: isPortrait ? width ***** 0.57 : height ***** 0.54, y: isPortrait ? ( height ***** 0.25 - height ***** 0.25 ***** CGFloat (self. progress ) ***** CGFloat ( coefficientShape ) - 27) : ( width ***** (0.25 - 0.25 ***** CGFloat (self. progress ) ***** CGFloat ( coefficientShape )) - 5)))

path. closeSubpath ()

}

//.animation(.linear(duration: 7.0))

Slider (value: $temperature , in: -1.0 1.0, step: 0.1)

// .animation(.linear(duration: 5.0))

Text ("( temperature )")

}

. onChange (of: temperature , perform: { value in

self. progress = self. temperature ***** 2

}). animation (. linear (duration: 25.0))

}

}

struct ContentView_Previews: PreviewProvider {

static var previews : some View {

ContentView (progress: Double ())

}

}


#2
  1. Отформатируйте код для начала.

  2. Формулируйте вопрос нормально: а что вы хотели анимировать?

  3. модификатор .animation применяется для Вью (SwiftUI 1-2), соответственно он у вас срабатывает при инициализации вью.

  4. Если вам надо анимировать изменение переменных, то сами эти действия (изменение переменных или присвоение им значений) помещаются в блок

    withAnimation {
    }
    

PS в SwiftUI 3 будет доступна возможность применять модификатор .animation к биндевым переменным, например в тоглах или сладерах.


#3

Уважаемый ODIN, извиняюсь за четыре звездочки в коде вместо одной это глюк компьютера.
Мне нужно, что бы треугольник, получаемый из фигуры Path в зависимости от положения слайдера перемещался с анимацией вертикально по экрану. Вся анимация, которую вы перечислили, не работает. Я в тупике, поэтому и написал на форум. Вот то о чем вы говорили.
struct ContentView: View{

var width = UIScreen. main . bounds . width

var height = UIScreen. main . bounds . height

var coefficientShape = UIScreen. main . bounds . width. UIScreen . main . bounds . height

@ State var isPortrait: Bool = true

@ State var progress: Double = 0.0

@ State var temperature: Double = 0.0

var body: some View {

VStack {

withAnimation {

Path {path in

path. move (to: CGPoint (x: isPortrait ? width * 0.53 : height * 0.52, y: isPortrait ? ( height * 0.25 - 0.25 * height * CGFloat (self. progress ) * CGFloat ( coefficientShape ) - 20) : (width * (0.25 - 0.25 * CGFloat** (self. progress ) * CGFloat ( coefficientShape )))))

path. addLine (to: CGPoint (x: isPortrait ? width * 0.57 : height * 0.54, y: isPortrait ? (0.25 * height - 0.25 * height * CGFloat (self. progress ) * CGFloat ( coefficientShape ) - 16) : ( width * (0.25 - 0.25 * CGFloat** (self. progress ) * CGFloat ( coefficientShape )) + 5)))

path. addLine (to: CGPoint (x: isPortrait ? width * 0.57 : height * 0.54, y: isPortrait ? ( height * 0.25 - height * 0.25 * CGFloat (self. progress ) * CGFloat ( coefficientShape ) - 27) : ( width * (0.25 - 0.25 * CGFloat (self. progress ) * CGFloat ( coefficientShape )) - 5)))

path. closeSubpath ()

}
}

// .animation(.linear(duration: 7.0))

Slider(value: $temperature . animation(.linear(duration: 5.0)), in: -1.0…1.0, step: 0.1)

// .animation(.linear(duration: 5.0))

Text("( temperature )")

}

. onChange(of: temperature, perform: { value in

self.progress = self. temperature / 2

})//.animation(.linear(duration: 25.0))

}
}

struct ContentView_Previews: PreviewProvider{

static var previews: someView{

ContentView(progress: Double())

}
}

P.S. Анимации нет не в Canvas не в Simulator.


#4

Отформатировал код

struct ContentView: View{
 var width = UIScreen. main . bounds . width
 var height = UIScreen. main . bounds . height
 var coefficientShape = UIScreen. main . bounds . width. UIScreen . main . bounds . height

@ State var isPortrait: Bool = true
@ State var progress: Double = 0.0
@ State var temperature: Double = 0.0

var body: some View {
     VStack {
   withAnimation {
    Path {path in
      path. move (to: CGPoint (x: isPortrait ? width * 0.53 : height * 0.52, y: isPortrait ? ( height * 0.25 - 0.25 * height * CGFloat (self. progress ) * CGFloat ( coefficientShape ) - 20) : (width * (0.25 - 0.25 * CGFloat** (self. progress ) * CGFloat ( coefficientShape )))))
      path. addLine (to: CGPoint (x: isPortrait ? width * 0.57 : height * 0.54, y: isPortrait ? (0.25 * height - 0.25 * height * CGFloat (self. progress ) * CGFloat ( coefficientShape ) - 16) : ( width * (0.25 - 0.25 * CGFloat** (self. progress ) * CGFloat ( coefficientShape )) + 5)))
      path. addLine (to: CGPoint (x: isPortrait ? width * 0.57 : height * 0.54, y: isPortrait ? ( height * 0.25 - height * 0.25 * CGFloat (self. progress ) * CGFloat ( coefficientShape ) - 27) : ( width * (0.25 - 0.25 * CGFloat (self. progress ) * CGFloat ( coefficientShape )) - 5)))
      path. closeSubpath ()
    }
  }

// .animation(.linear(duration: 7.0))
Slider(value: $temperature . animation(.linear(duration: 5.0)), in: -1.0…1.0, step: 0.1)
// .animation(.linear(duration: 5.0))
Text("( temperature )")
}

. onChange(of: temperature, perform: { value in
      self.progress = self. temperature / 2

     })//.animation(.linear(duration: 25.0))
  }
}

  struct ContentView_Previews: PreviewProvider{
         static var previews: someView{
             ContentView(progress: Double())
  }
}

#5

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

import SwiftUI

struct ContentView: View {
var width = UIScreen.main.bounds.width
var height = UIScreen.main .bounds .height
var coefficientShape = UIScreen.main.bounds.width/UIScreen.main.bounds.height
@State var isPortrait: Bool = true
@State var progress: Double = 0.0
@State var temperature: Double = 0.0
var body: some View{
VStack{
withAnimation{
Path {path in
path.move (to: CGPoint(x: isPortrait ? width * 0.53 :
height * 0.52, y: isPortrait ? ( height * 0.25 -
0.25 * height * CGFloat(self.progress) * CGFloat(coefficientShape) - 20)
: (width * (0.25 - 0.25 * CGFloat (self.progress) * CGFloat(coefficientShape )))))
path.addLine(to: CGPoint(x: isPortrait ? width * 0.57 : height * 0.54,
y: isPortrait ? (0.25 * height - 0.25 * height * CGFloat(self.progress)
* CGFloat( coefficientShape) - 16) :
(width * (0.25 - 0.25 * CGFloat (self.progress ) * CGFloat(coefficientShape)) + 5)))
path.addLine(to: CGPoint(x: isPortrait ? width * 0.57 : height * 0.54,
y: isPortrait ? (height * 0.25 - height *
0.25 * CGFloat(self.progress) * CGFloat(coefficientShape) - 27) :
(width * (0.25 - 0.25 * CGFloat(self.progress) * CGFloat(coefficientShape)) - 5)))
path.closeSubpath()
}
}
Slider(value:$progress.animation(.linear(duration: 5.0)), in: -5.0…2.0, step: 0.1)
// .animation(.linear(duration: 5.0))
Text("(progress)")
}
}
}
struct ContentView_Previews: PreviewProvider{
static var previews : some View {
ContentView (progress: Double())
}
}


#6

Вы пытатесь анимировать отрисовку треугольника. А вам надо в блок withAnimation{} вставить изменение переменных, определяющих изменение координат вашего треугольника (то есть само изменение переменных: например progress + 1). Это видимо progress у вас, но я не уверен.


#7

Я как раз и анимирую изменение progress в слайдере Slider(value:$progress.animation(.linear(duration: 5.0)), in: -5.0…2.0, step: 0.1). Однако это почему-то не работает?


#8

вы работаете в бете xcode13?


#9

Нет, я работаю в 12.5.1.


#10

ну насколько помню в swiftui2 не работает анимация биндевых переменных, только со swiftui3. Для вас тогда решение перетащить блок анимации в сеттер переменной progress