[3]SwiftUI
程序员文章站
2024-03-24 12:42:22
...
Transition
移动用Transition,变化用Animation
.asymmetric可以将进入进出动画分离各自设置
.combined丰富动画内容
AnyTransition表面显示多种动画
HikeDetail(hike: hike)
.transition(.moveAndFade)
extension AnyTransition {
static var moveAndFade: AnyTransition{
let insertion = AnyTransition.move(edge: .trailing).combined(with: .opacity)
let removal = AnyTransition.scale.combined(with: .opacity)
return .asymmetric(
insertion: insertion,
removal: removal
)
}
}
Animation
spring有弹簧的效果
delay将图片按照index一个个出现 * 0.03 设置了速度
var rippling: Animation{
Animation.spring(dampingFraction: 0.5)
.speed(2)
.delay(Double(index) * 0.03)
}
var body: some View {
Capsule()
.fill(Color.white)
.frame(height: height * heightRatio, alignment: .bottom)
.offset(x: 0, y: height * -offsetRatio)
.animation(rippling)
}
.rotationEffect(.degrees(showDetail ? 90 : 0))旋转
.scaleEffect(showDetail ? 1.5 : 1)放大
Button(action: {
withAnimation() {
self.showDetail.toggle()
}
}) {
Image(systemName: "chevron.right.circle")
.imageScale(.large)
.rotationEffect(.degrees(showDetail ? 90 : 0))
.scaleEffect(showDetail ? 1.5 : 1)
.padding()
.animation(.spring())
}
数据分类
将数据分类得到一个Dictionary类的数据
var categories: [String:[Landmark]] {
Dictionary(
grouping: landmarks,
by: {$0.category}
)
}
NavigationView、List和ScrollView的嵌套
NavigationView {
List {
Image(***)
ForEach(categories.keys.sorted(),id: \.self) {
categoryName in
VStack(alignment:.leading) {
Text(categoryName)
.font(.headline)
ScrollView(.horizontal,showsIndicators: false) {
HStack(spacing: 15){
ForEach(categorie[categoryName]!) {
landmark in
CategoryItem(landmark: landmark)
}
}
}
}
.padding(.top,8)
.padding(.bottom,8)
}
NavigationLink(destination:LandmarkList().environmentObject(UserData())) {
Text("查看所有地标")
}
}
.navigationBarTitle(Text("精选"))
}
无NavigationView下的NavigationLink
Image下的.renderingMode要配置为.original
NavigationLink(
destination: LandmarkDetail(landmark: landmark).environmentObject(UserData())
) {
VStack(alignment:.leading) {
Image(landmark.imageName)
.renderingMode(.original)
.resizable()
.frame(width: 155,height: 155)
.cornerRadius(5)
Text(landmark.name)
.font(.caption)
.foregroundColor(.primary)
}
}