#ios #swift #swiftui
#iOS #swift #swiftui
Вопрос:
Я ломал голову над созданием желаемого matchedGeometryEffect с помощью SwiftUI 2. Во время этого процесса обучения что-то прошло мой путь, который я действительно не могу объяснить. Я покажу пример.
Я пытаюсь создать переход Список -> Детали с эффектом, обычно называемым эффектом «Героя». Изображение профиля в представлении списка переходит к большому баннеру в подробном представлении.
Для достижения этой цели я создал два KFImages (KF = Kingfisher, пакет, который я использую для удобной загрузки и кэширования изображений) с несколькими модификаторами:
Просмотр списка:
if !isProductDetailViewPresented {
KFImage(store.results.first?.images?.first?.url)
.resizable()
.cornerRadius(30)
.scaledToFill()
.matchedGeometryEffect(id: "image.testprod", in: animationNamespace!, anchor: .center, isSource: !isProductDetailViewPresented)
.animation(.easeInOut(duration: 0.3))
.frame(width: 60, height: 60, alignment: .center)
.zIndex(999)
}
Подробный просмотр:
if isProductDetailViewPresented {
...
KFImage(product?.images?.first?.url)
.resizable()
.scaledToFill()
.cornerRadius(30)
.matchedGeometryEffect(id: "image.testprod", in: animationNamespace!, anchor: .center, isSource: isProductDetailViewPresented)
.frame(height: 300)
.animation(.easeInOut(duration: 0.3))
...
}
… это почти сработало; каким-то образом мое изображение не будет ограничиваться .frame(width: 60, height: 60)
. Вместо этого он растягивается, чтобы поместить изображение в представление, делая ширину больше 60. Высота остается на уровне 60.
Чтобы исправить это, я подумал; возможно, этот .frame()
модификатор следует поместить перед .matchedGeometryEffect()
модификатором. Но когда я это делаю, меняется только положение двух изображений; не размер. Это заставляет меня думать, что .matchedGeometryEffect()
модификаторы считают фреймы «фиксированными» для размещения .frame()
модификаторов перед .matchedGeometryEffect()
модификаторами.
Это странно, так как несколько примеров в Интернете показывают код, в котором .frame()
вызывается раньше .matchedGeometryEffect()
, например , здесь (поиск .matchedGeometryEffect()
, их всего 2) и здесь (раздел «Следовать за последователем»).
Два вопроса:
-
Почему мой работает только тогда, когда я звоню
.frame()
после.matchedGeometryEffect()
, в то время как онлайн-источники делают обратное? -
Как
.matchedGeometryEffect()
обрабатывать порядок модификаторов? Что я должен принять во внимание?
Честно говоря, я довольно плохо разбираюсь в этом API. Я надеюсь, что вы, ребята, сможете прояснить ситуацию для меня. 🙂
Комментарии:
1. У вас когда-нибудь был этот уточненный Jaap? 🙂 Возможно, это я задал ваш вопрос сегодня вечером.