Вопрос или проблема
Я пытаюсь переместить изображение справа налево для анимации, но не знаю, как изменить начальную и конечную позицию в зависимости от типа устройства: iPad или iPhone. Я не могу задать xpos и ypos для начальной позиции внутри view, иначе получаю ошибку ‘Type () cannot conform to View’, поэтому я переместил код в .onAppear, который задает xpos и ypos в зависимости от типа устройства, но этот код выполняется после того, как начальная позиция уже установлена. Код ниже
import Foundation
import SwiftUI
struct Home1View: View {
@State var xpos: CGFloat = 350
@State var ypos: CGFloat = 450
@State var opac: Double = 1.0
@State var dHeight: Int = 0
let layoutProperties:LayoutProperties
var body: some View {
GeometryReader { geometry in
ZStack {
ResponsiveView {properties in
VStack{
Text("XXXX")
Image("number-one")
.resizable()
.frame(width: layoutProperties.dimensValues.frameSz, height: layoutProperties.dimensValues.frameSz)
.position(x: xpos, y: ypos)
.opacity(opac)
.onAppear {
//iPad 13 дюймов ширина = 1032 высота 870
print("высота дисплея при отображении = ", geometry.size.height)
print("ширина дисплея при отображении = ", geometry.size.width)
xpos = geometry.size.width - 100
ypos = geometry.size.height - 150
withAnimation(Animation.easeInOut(duration: 3).repeatCount(2, autoreverses: false)) {
xpos = 100
//.position(x: layoutProperties.dimensValues.xpos, y: layoutProperties.dimensValues.ypos-250)
} completion: {
opac = 0.0
}
}
} //конец ZStack
} //конец geometry
}
}
Ответ или решение
Чтобы установить начальную позицию анимации изображения в зависимости от типа устройства (iPhone или iPad), вы можете использовать условную логику в методе .onAppear()
, а также корректировать начальные координаты на основании ширины и высоты экрана. Вы правы, что изменения в @State
переменных, таких как xpos
и ypos
, должны происходить в рамках логики вашего интерфейса. Однако @State
переменные не могут быть использованы для инициализации позиции непосредственно в view body
, так как они должны оставаться в соответствии с жизненным циклом SwiftUI.
Вот пример, как можно структурировать ваш код, чтобы правильно устанавливать переменные в зависимости от типа устройства:
import Foundation
import SwiftUI
struct Home1View: View {
@State private var xpos: CGFloat = 0
@State private var ypos: CGFloat = 0
@State private var opac: Double = 1.0
var body: some View {
GeometryReader { geometry in
ZStack {
VStack {
Text("XXXX")
Image("number-one")
.resizable()
.frame(width: 100, height: 100) // Установите здесь свои значения
.position(x: xpos, y: ypos)
.opacity(opac)
.onAppear {
// Определите устройство на основе его размеров
if geometry.size.width > 768 { // Пороговое значение для iPad
xpos = geometry.size.width - 100
ypos = geometry.size.height - 150
} else {
xpos = 350
ypos = 450
}
withAnimation(Animation.easeInOut(duration: 3).repeatCount(2, autoreverses: false)) {
xpos = 100
} completion: {
opac = 0.0
}
}
}
}
.frame(width: geometry.size.width, height: geometry.size.height)
}
}
}
Объяснение кода:
-
Условная логика: Мы используем условие
if geometry.size.width > 768
, чтобы различать iPad и iPhone. Это основано на том, что iPad имеет ширину больше, чем 768 пикселей, в то время как iPhone, как правило, меньше. -
Инициализация позиций: В методе
.onAppear
мы устанавливаемxpos
иypos
в зависимости от типа устройства. Для iPad, мы устанавливаем значения в зависимости от ширины и высотыgeometry
, а для iPhone – используем статические значения. - Анимация: Мы объявляем анимацию, которая будет перемещать изображение с новыми значениями pos используя
.position()
.
Таким образом, при запуске анимации, изображение будет начинать с корректной позиции в зависимости от устройства, и вы избежите ошибки, связанной с использованием значений state переменных вне контекста view body.