SwiftUI에서 View 건너뛰기(even-od rule algorithm)

개시하다


SwiftUI 초보자인 아마존입니다.
며칠 전에 나는 내가 쓴 2년 전의 자료를 도울 수 있었던 경험이 있다.
그래서 오늘 저는 2년 후의 자신과 이 세상에서 어려움을 겪는 사람들이 SwiftUI에서 View를 추출하는 방법과 도중에 만나는 재미있는 알고리즘을 기록하고 싶습니다.

이루어지다


말하자면, 소뿔을 파고드는 것은 도대체 무엇입니까?
예전에 이런 UI가 있었죠.

저는 이런 사람이 되고 싶어요.
반투명한view로 전체 화면을 덮어 주의를 끌고 싶은 곳만 눈에 띄게 파낸다.
다양한 실현 방법이 있지만, 이번에는 스위프트 UI의 Path와 이번 흥미로운 장소 이벤트-od rule algorithm으로 진행하고 싶습니다.

시험해 보다


우선 기본적인 화면을 준비한다.
문자는 검은색 반투명 도면층 상태의 화면으로 중앙에 표시됩니다.
    var body: some View {
        ZStack {
            VStack(spacing: 15) {
                Text("First, tap here.")
                Text("Next, tap here💡")
                Text("Finally, tap here.")
            }
            Rectangle()
                .foregroundColor(Color.black.opacity(0.8))
        }
        .edgesIgnoringSafeArea(.all)
    }
간단합니다.이런느낌↓

그럼 바로 짬을 내고 싶습니다.
제가 먼저 "mask 쓰면 되지 않나요?"내 생각엔

이런 느낌이지만 하고 싶은 것과는 상반된다.
하고 싶은 일은 이것과 상반된다.어떻게 하면 좋을까요?
그곳에서 발견된 것은 even-odd rule algorithm이다.
DeepL씨의 도움을 빌려 이런 설명을 썼을 거라고 생각합니다.
이 규칙은 점에서 무한대로 큰 방향으로 선을 그리고 그 선이 교차하는 도형에서 경로 세그먼트의 수를 계산하여 캔버스의 점의 '진실하지 않음' 을 확인합니다.이 숫자가 홀수이면 점이 안쪽에 있고 짝수이면 바깥쪽에 있습니다.
이번에는 하고 싶은 일을 바탕으로 그림을 그려 보았다.

하고 싶은 일을 바탕으로 그린 그림
핑크 라인은 마스크를 위한 팻.
그리고 한 가지 요점은 A라고 생각해요.그것은 상술한 "그 점"과 필적하는 것이다.설명에 따라 이 점들에서 매우 긴 파란색 선을 그렸다.그러면 핑크 Path와 교차하는 곳이 생기죠.그것이 바로 설명된 경로 세그먼트입니다.
경로 세그먼트의 수량을 계산하여 캔버스의 점의 '진실하지 않음' 을 확인합니다.점에서 뻗어 나온 초장선과 Path가 교차하는 곳의 수에 따라'그 점'이 있는 곳이 안쪽인지 바깥쪽인지를 결정하는 것이다.
이 알고리즘을 마스크를 쓴 Path에 적용하면 중점 A가 안쪽에 있으면 마스크를 쓰고, 처음 마스크를 썼을 때처럼 하고 싶은 일과 반대되는 상태가 되기 때문에 중점 A가 바깥쪽에 있는 게 좋다는 것이다.알고리즘 규칙을 보다
이 숫자가 홀수이면 점이 안쪽에 있고 짝수이면 바깥쪽에 있습니다.
점 A에서 뻗어나온 선과 마스크의 Path가 교차하는 곳의 수를 짝수로 만들려는 것이다.
그럼 어떡하지?밖에 Path를 하나 더 넣었으면 좋겠어요 (단순)💡

Path 그림 추가
A점에서 뻗은 선과 Path가 교차하는 곳에서 짝수로 바뀌었다!
그리고 B부터 연장하는 선을 주의하세요.A점의 결과와 반대로 교차하는 곳이 홀수로 변했다!재미있다~✨
그리고 그걸 실행해보면...

'이런 사람 하고 싶어요'그림이랑 똑같은 느낌이에요.🎉
코드하면 대충 이런 느낌↓
FillStyle(eoFill:true)이 되는 곳, 이벤트-odle algorithm에 적응하는 곳입니다.
struct ContentView: View {
    var body: some View {
        ZStack {
            VStack(spacing: 15) {
                Text("First, tap here.")
                Text("Next, tap here💡")
                Text("Finally, tap here.")
            }
            Rectangle()
                .foregroundColor(Color.black.opacity(0.8))
                .mask(
                    rectangleShapeMaskPath(getRectangleRectFromCenter(with: 25,
                                                                      width: 200))
                        .fill(style: FillStyle(eoFill: true))
                )
        }
        .edgesIgnoringSafeArea(.all)

    }

    private func rectangleShapeMaskPath(_ rect: CGRect) -> Path {
        // 外側のPath
	var shape = Path(CGRect(origin: .zero, size: UIScreen.main.bounds.size)) 
	// 内側のPath
        shape.addPath(Path(rect)) 
        return shape
    }

    private func getRectangleRectFromCenter(with hight: CGFloat, width: CGFloat) -> CGRect {
        let point = getRectanglePointFromCenter(width: width, height: hight)
        return CGRect(x: point.x, y: point.y, width: width, height: hight)
    }

    private func getRectanglePointFromCenter(width: CGFloat, height: CGFloat) -> CGPoint {
        let screenSize = UIScreen.main.bounds.size
        let center = CGPoint(x: screenSize.width / 2, y: screenSize.height / 2)
        let x = center.x - (width / 2)
        let y = center.y - (height / 2)
        return CGPoint(x: x, y: y)
    }
}
물론 원형, 삼각형 등 다른 형태의 경로도 같을 수 있다.그리고 가고 싶은 곳에 관해서는 이번에도 센터에서만 한정된 형태로 설치를 했는데 좋아하는 곳에 두면 더 좋을 것 같아요.

총결산


어때요, 이벤트-odd rule algorithm.
디자이너의 당연한 지식인가?내 생각엔
나는 어떻게 말해야 할지 몰랐다. "오, 뭔지 모르겠지만 이루어졌어! 좋아!"이런 가능성은 크지만'이필'이라든가 하면서 깊이 파헤쳐 봤는데 의외로 재밌는 알고리즘을 만나게 돼서 너무 좋았어요.😊
재밌는 거 어디 숨겼는지 모르겠네.
참조:
https://docs.microsoft.com/ja-jp/xamarin/xamarin-forms/user-interface/shapes/fillrules
https://stackoverflow.com/questions/46017839/how-does-fill-rule-evenodd-work-on-a-star-svg
PS: 기대된다.반드시 월급이 있어야 한다.

좋은 웹페이지 즐겨찾기