ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • iOS, Swift에서 swipe back 제스처 인식기 추가
    Language/iOS,AOS 2024. 12. 26. 17:10

     

    메인 WKWebView Swipe 활성화

    • Swipe로 뒤로가기, 앞으로가기 활성화
    override func viewDidLoad() {
      ...
      wKMainWeb?.allowsBackForwardNavigationGestures = true
      ...
    }
    • Swipe로 뒤로가기, 앞으로가기 비활성화
    override func viewDidLoad() {
      ...
      wKMainWeb?.allowsBackForwardNavigationGestures = false
      ...
    }

     

    팝업 UIView 설정

    UIView등 새창으로 생성되는곳에 코드를 삽입해준다.

    • 팝업 호출시 스와이프 백 제스처 인식기 추가
    // MARK: - iOS Bridge
    // 웹 액션 정의 : WebAction을 구분하는데 사용되는 타입
    enum WebAction: String {
        ...
        case windowFull
        ...
    }
    extension MainViewController: WKScriptMessageHandler {
        func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
            guard message.name == IOS_BRIDGE_NAME,
                  let messageBody = message.body as? [String: Any],
                  let action = messageBody["action"] as? String else { return }
            
            let webAction = WebAction(rawValue: action)
            
            Utils.Log("@@@@@@@@@@@@@@@@@@@@@@@ \(action)")
            
            switch webAction {
            ...
            
            case .windowFull:
                guard let params: [String: String] = messageBody["params"] as? [String: String],
                      let url: String = params["url"] else {
                    return
                }
                
                let popupView: PopupView = Utils.cretePopupView(viewMainWeb, viewType: ViewType.INNER_POPUP);
                let popupWKWebView: WKWebView = createWKWebView(popupView.contentView, configuration: getWKWebViewConfiguration())
                
                loadWKWebView(wkWebView: popupWKWebView, url: url)
                
                // 스와이프 백 제스처 인식기 추가
                let swipeBackGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:)))
                popupView.addGestureRecognizer(swipeBackGesture)
                
            default:
                ...
            }
        }
            
        @objc func handlePanGesture(_ gesture: UIPanGestureRecognizer) {
            guard let popupView = gesture.view else { return }
            let translation = gesture.translation(in: view)
            
            switch gesture.state {
            case .changed:
                if translation.x > 0 {
                    let progress = translation.x / view.bounds.width
                    // popupView만 이동
                    popupView.transform = CGAffineTransform(translationX: translation.x, y: 0)
                    // 배경 알파값 조정
                    self.view.backgroundColor = UIColor.black.withAlphaComponent(0.5 * (1 - progress))
                }
            case .ended:
                let velocity = gesture.velocity(in: view).x
                // 스와이프 속도나 이동 거리를 기준으로 닫기 여부 결정
                if translation.x > view.bounds.width / 3 || velocity > 500 {
                    UIView.animate(withDuration: 0.3, animations: {
                        popupView.transform = CGAffineTransform(translationX: self.view.bounds.width, y: 0)
                        self.view.backgroundColor = UIColor.black.withAlphaComponent(0)
                    }) { _ in
                        self.removeLastPopupView()
                    }
                } else {
                    // 원위치로 되돌리기
                    UIView.animate(withDuration: 0.3) {
                        popupView.transform = .identity
                        self.view.backgroundColor = UIColor.black.withAlphaComponent(0.5)
                    }
                }
            case .cancelled:
                // 제스처가 취소된 경우 원위치로
                UIView.animate(withDuration: 0.3) {
                    popupView.transform = .identity
                    self.view.backgroundColor = UIColor.black.withAlphaComponent(0.5)
                }
            default:
                break
            }
        }
        
    }

     

    이렇게 했더니 스와이프 백 제스처 사용 시 상태 바 영역이 검은색으로 보이는 문제가 발생하였다.

    그래서 아래와 같이 코드를 수정하였다.

    @objc func handlePanGesture(_ gesture: UIPanGestureRecognizer) {
        guard let popupView = gesture.view else { return }
        let translation = gesture.translation(in: view)
        
        // 배경 뷰를 별도로 관리
        let backgroundView = popupView.superview?.viewWithTag(999) ?? {
            let bgView = UIView(frame: view.bounds)
            bgView.tag = 999
            bgView.backgroundColor = UIColor.black.withAlphaComponent(0.5)
            bgView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
            popupView.superview?.insertSubview(bgView, at: 0)
            return bgView
        }()
        
        switch gesture.state {
        case .changed:
            if translation.x > 0 {
                let progress = translation.x / view.bounds.width
                // popupView만 이동
                popupView.transform = CGAffineTransform(translationX: translation.x, y: 0)
                // 배경 알파값 조정
                backgroundView.alpha = 1 - progress
            }
            
        case .ended:
            let velocity = gesture.velocity(in: view).x
            // 스와이프 속도나 이동 거리를 기준으로 닫기 여부 결정
            if translation.x > view.bounds.width / 3 || velocity > 500 {
                UIView.animate(withDuration: 0.3, animations: {
                    popupView.transform = CGAffineTransform(translationX: self.view.bounds.width, y: 0)
                    backgroundView.alpha = 0
                }) { _ in
                    backgroundView.removeFromSuperview()
                    self.removeLastPopupView()
                }
            } else {
                // 원위치로 되돌리기
                UIView.animate(withDuration: 0.3) {
                    popupView.transform = .identity
                    backgroundView.alpha = 1
                }
            }
            
        case .cancelled:
            // 제스처가 취소된 경우 원위치로
            UIView.animate(withDuration: 0.3) {
                popupView.transform = .identity
                backgroundView.alpha = 1
            }
            
        default:
            break
        }
    }

     

    짝짝짝!!

    댓글

Designed by Tistory.