Dev.YoungKyu
YoungKyu's Devlog
전체 방문자
오늘
어제
  • 분류 전체보기 N
    • 부스트캠프
    • iOS
    • visionOS
    • Backend N
    • 알고리즘
    • CS
    • Git
    • Python
    • 끄적끄적

블로그 메뉴

  • 홈
  • 🌝 티스토리 홈
  • ⭐️ 깃허브
  • 태그

공지사항

인기 글

최근 댓글

최근 글

태그

  • avaudiosessionportdescription
  • jekyll
  • Concurrency
  • 백준
  • 모듈화
  • 부스트캠프
  • AVAudioSession
  • ios
  • 소프트웨어 공학
  • boj
  • 소프트웨어공학
  • 알고리즘
  • 오블완
  • Swift5.7
  • swift
  • CS
  • Animation
  • 소프트웨어 테스트
  • Git
  • constraint
  • Python
  • SwiftUI
  • ImageResource
  • 티스토리챌린지
  • if let
  • MVC
  • guard
  • AutoLayout
  • Optional
  • image

티스토리

hELLO · Designed By 정상우.
Dev.YoungKyu
[SwiftUI]커스텀 백버튼 백 제스처 시 화면 멈춤 이슈 해결
iOS

[SwiftUI]커스텀 백버튼 백 제스처 시 화면 멈춤 이슈 해결

2022. 9. 11. 15:22

XCode : 13.2.1
타겟 버전 : 14.0 이후
시뮬레이터 버전 : 15.2

개요

프로젝트를 진행하면서 디자이너님의 요구사항에 맞게 백버튼을 커스텀해야 할 일이 생겼다. 그러나 SwiftUI에선 아직 NavigationBar 백버튼의 디자인을 바꿀 수 있는 옵션을 제공하지 않아 커스텀하여 사용하기로 했다. 그러나 커스텀 백버튼을 만들고 hidden 옵션을 주면 백 제스처가 동작하지 않았고

.navigationBarHidden(true)

찾다보니 UINavigationController를 직접 수정하면 해결 할 수 있다고 했다.

interactivePopGestureRecognizer?.delegate = self

그러나 Navigation Stack에 뷰가 하나밖에 없는데 뷰를 pop 해버리면 안되기때문에 view가 2개 이상일 경우에만 동작하도록 처리가 필요했다.

문제된 기존 코드 (따라하지 마세요ㅜㅜ)

extension UINavigationController : UINavigationControllerDelegate {
    open override func viewDidLoad() {
        super.viewDidLoad()
        interactivePopGestureRecognizer?.delegate = nil
    }

    public func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
        self.interactivePopGestureRecognizer?.isEnabled = self.viewControllers.count > 1
    }

}

당시엔 시험기간이기도 하고 풀리지 않을 것 같은 버그에 뇌정지가 와서 한참동안 내려놓고 있다가 종강하고 다시봤더니 이게 뭐람
천천히 뇌버깅 해보니 네비게이션 뷰가 viewDidLoad() 될때마다 해당 네비게이션 뷰의 delegate를 날려버리니까 아무리 isEnabled해도 안됐던 것이다.🤯

self.interactivePopGestureRecognizer? // 여기서 이미 nil

기존 버그 현상

수정 전

수정된 코드

extension UINavigationController : UINavigationControllerDelegate, UIGestureRecognizerDelegate {
    open override func viewDidLoad() {
        super.viewDidLoad()
        interactivePopGestureRecognizer?.delegate = self
    }

    // MARK :  Navigation Stack에 쌓인 뷰가 1개를 초과해야 제스처가 동작 하도록
    public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
            return viewControllers.count > 1
    }

}

그렇게 다른 레퍼런스를 통해 gestureRecognizerShouldBegin을 알게되어 Navigation Stack 에 쌓인 뷰가 1개를 넘을때만 제스처가 동작하도록 바꿨더니 해결되었다! 너무 후련 😞

버그 수정

수정 후


초기화면에서 백 제스처 시 Navigation Stack에 View가 하나밖에 없어 제스처가 동작하지 않는 모습

참고링크

https://medium.com/hcleedev/swift-custom-navigationview%EC%97%90%EC%84%9C-swipe-back-%EA%B0%80%EB%8A%A5%ED%95%98%EA%B2%8C-%ED%95%98%EA%B8%B0-c3c519c59bcb

'iOS' 카테고리의 다른 글

Swift 5.7 - if let 문 간략화  (0) 2022.09.13
Swift 5.7 릴리즈 - 언어 및 표준라이브러리, 개발자 경험  (0) 2022.09.13
[iOS]카카오 로그인 구현 시 키 값 숨기기  (0) 2022.09.11
[iOS][Swift] 프로토콜 vs 인터페이스 차이점  (1) 2022.09.11
[iOS][Swift] guard 문  (0) 2022.09.11
    'iOS' 카테고리의 다른 글
    • Swift 5.7 - if let 문 간략화
    • Swift 5.7 릴리즈 - 언어 및 표준라이브러리, 개발자 경험
    • [iOS]카카오 로그인 구현 시 키 값 숨기기
    • [iOS][Swift] 프로토콜 vs 인터페이스 차이점
    Dev.YoungKyu
    Dev.YoungKyu
    iOS를 공부하고 있습니다

    티스토리툴바