Positioning View using anchor point

前端 未结 3 1599
遥遥无期
遥遥无期 2021-01-02 19:25

I have several dozen Texts that I would like to position such that their leading baseline (lastTextBaseline) is at a specific coordinate. position

3条回答
  •  清酒与你
    2021-01-02 20:05

    this code takes care of the font metrics, and position text as you asked (If I properly understood your requirements :-))

    import SwiftUI
    import PlaygroundSupport
    
    
    struct BaseLine: ViewModifier {
        let alignment: HorizontalAlignment
        @State private var ref = CGSize.zero
        private var align: CGFloat {
            switch alignment {
            case .leading:
                return 1
            case .center:
                return 0
            case .trailing:
                return -1
            default:
                return 0
            }
        }
        func body(content: Content) -> some View {
            ZStack {
                Circle().frame(width: 0, height: 0, alignment: .center)
            content.alignmentGuide(VerticalAlignment.center) { (d) -> CGFloat in
                DispatchQueue.main.async {
                    self.ref.height =  d[VerticalAlignment.center] - d[.lastTextBaseline]
                    self.ref.width = d.width / 2
                }
                return d[VerticalAlignment.center]
            }
            .offset(x: align * ref.width, y: ref.height)
            }
        }
    }
    
    struct ContentView: View {
        var body: some View {
            ZStack {
    
                Cross(size: 20, color: Color.red).position(x: 200, y: 200)
                Cross(size: 20, color: Color.red).position(x: 200, y: 250)
                Cross(size: 20, color: Color.red).position(x: 200, y: 300)
                Cross(size: 20, color: Color.red).position(x: 200, y: 350)
    
    
                Text("WORLD").font(.title).border(Color.gray).modifier(BaseLine(alignment: .trailing))
                    .rotationEffect(.degrees(45))
                    .position(x: 200, y: 200)
    
                Text("Y").font(.system(size: 150)).border(Color.gray).modifier(BaseLine(alignment: .center))
                .rotationEffect(.degrees(45))
                .position(x: 200, y: 250)
    
                Text("Y").font(.system(size: 150)).border(Color.gray).modifier(BaseLine(alignment: .leading))
                .rotationEffect(.degrees(45))
                .position(x: 200, y: 350)
    
                Text("WORLD").font(.title).border(Color.gray).modifier(BaseLine(alignment: .leading))
                    .rotationEffect(.degrees(225))
                    .position(x: 200, y: 300)
    
            }
        }
    }
    
    struct Cross: View {
        let size: CGFloat
        var color = Color.clear
        var body: some View {
                Path { p in
                    p.move(to: CGPoint(x: size / 2, y: 0))
                    p.addLine(to: CGPoint(x: size / 2, y: size))
                    p.move(to: CGPoint(x: 0, y: size / 2))
                    p.addLine(to: CGPoint(x: size, y: size / 2))
                }
                .stroke().foregroundColor(color)
                .frame(width: size, height: size, alignment: .center)
        }
    }
    
    PlaygroundPage.current.setLiveView(ContentView())
    

提交回复
热议问题