ios 如何让3个组合的“SF Symbol”图像围绕特定点旋转?

a0zr77ik  于 2024-01-09  发布在  iOS
关注(0)|答案(1)|浏览(108)

我有三(3)个SF Symbols分组,并以特定的关系排列。现在我希望整个组作为一个项目围绕特定的点旋转。


的数据
我已经花了几个小时的试错(主要是错误),试图调整paddingoffsetsanchor points的组合。

上下文:

此可旋转视图将用作iOS 17 Annotation的一部分,使用MapKit标记指示行进方向的特定GPS位置(因此旋转位和所需的锚点)。

如果有更好的方法来实现我的最终目标......我对所有的想法都持开放态度。

下面是我的代码:

import SwiftUI

struct StarArrowView: View {
   
   var bumpColor: Color
   @State var rotaAtAnchor = false
   var body: some View {
      ZStack {
         Divider()
         Divider().offset(y: 25)
         Divider().offset(y: -25)
         Divider().rotationEffect(.degrees(90))
         Divider().rotationEffect(.degrees(90)).offset(x: 25)
         Divider().rotationEffect(.degrees(90)).offset(x: -25)
         Group {
            HStack(spacing: 0) {
               Image(systemName: "star.fill")
                  .symbolRenderingMode(.palette)
                  .foregroundStyle(bumpColor)
                  .font(.system(size: 30, weight: .light))
                  .padding(0)
                  .offset(x: 8, y: 6)
               Image(systemName: "line.diagonal.arrow")
                  .foregroundStyle(bumpColor)
                  .font(.system(size: 40, weight: .light))
                  .padding(0)
                  .offset(x: -10, y: -15)
               Text("➘")
                  .symbolRenderingMode(.palette)
                  .foregroundStyle(bumpColor, bumpColor)
                  .font(.system(size: 30, weight: .ultraLight))
                  .rotationEffect(.degrees(190), anchor: .topLeading)
                  .padding(0)
                  .offset(x: 0, y: 0)
            }
            .padding(.vertical, -20)
            .padding(.horizontal, -5)
            .rotationEffect(.degrees(45))
            .offset(x: 15, y: 22)
            
            
            .rotationEffect(.degrees(rotaAtAnchor ? 0 : 180), anchor: .trailing) //Anchor Position
            .animation(Animation.spring ().repeatForever(autoreverses: true))
            .onAppear() {
               self.rotaAtAnchor.toggle()
            }
         }
      }
   }
}
   

#Preview {
   StarArrowView(bumpColor: .heatmap10)
}

字符串

jogvjijk

jogvjijk1#

关于这个问题的棘手部分是正确地获得锚点。一种方法是使用分数位置的UnitPoint。或者,为了使用组的一个边缘作为锚点,向上指向的箭头需要移动到组的边界之外。这可以使用叠加来完成。
这里是一个尝试,让它工作.一些笔记:

  • 当你在构建组和寻找锚点时,在单个项目后面放置一个彩色背景会有所帮助,这样框架就变得可见了。
  • 一个ZStack是用来合并的符号。我会建议,这比一个HStack更好地工作,因为有一些重叠涉及。
  • 在可能的情况下,填充优先于偏移。这样,项目在布局中的真实位置显示。
  • 指向上的箭头以.topTrailing对齐方式作为组的覆盖,然后以x偏移量移动到组的边缘上。
  • 为了确保指向上的箭头正好位于后缘的一半,它被赋予一个固定的宽度(任何大于自然宽度的尺寸都可以),然后x偏移量是这个宽度的一半。
ZStack {
    Divider()
    Divider().offset(y: 25)
    Divider().offset(y: -25)
    Divider().rotationEffect(.degrees(90))
    Divider().rotationEffect(.degrees(90)).offset(x: 25)
    Divider().rotationEffect(.degrees(90)).offset(x: -25)

    ZStack(alignment: .leading) {
        Image(systemName: "star.fill")
            .symbolRenderingMode(.palette)
            .foregroundStyle(bumpColor)
            .font(.system(size: 30, weight: .light))
            .rotationEffect(.degrees(45))
        Image(systemName: "line.diagonal.arrow")
            .foregroundStyle(bumpColor)
            .font(.system(size: 40, weight: .light))
            .rotationEffect(.degrees(45))
            .padding(.leading, 30)
    }
    .padding(.trailing, 10)
    .overlay(alignment: .topTrailing) {
        Text("➘")
            .symbolRenderingMode(.palette)
            .foregroundStyle(bumpColor, bumpColor)
            .font(.system(size: 30, weight: .ultraLight))
            .rotationEffect(.degrees(235))
            .frame(width: 30)
            .offset(x: 15)
    }
    .rotationEffect(.degrees(rotaAtAnchor ? 180 : 0), anchor: .trailing)

    // Fine adjustment of the position of the entire group
    .padding(.leading, 30)
    .padding(.top, 20)

    .animation(Animation.spring ().repeatForever(autoreverses: true), value: rotaAtAnchor)
    .onAppear() {
       self.rotaAtAnchor.toggle()
    }
}

字符串


的数据

相关问题