일모도원(日暮途遠) 개발자

[MacCatalyst] 웹뷰에서 키보드 타이핑이 안될때 본문

iOS개발/MacCatalyst

[MacCatalyst] 웹뷰에서 키보드 타이핑이 안될때

달님개발자 2022. 8. 24. 00:46

만들고 있는 맥카탈리스트용 동영상 플레이어에 단축키를 배정해놓았다.

그런데 웹뷰를 동영상뷰 위에 띄우니까 타이핑이 되지 않고, 단축키가 먹는 버그가 있었다.

 


해결책은 단축키가 있는 메뉴를 웹뷰가 뜰때는 없애주는거다.

 

메뉴가 있는 뷰(동영상 재생뷰)가 닫힐때는 메뉴를 diable해주고 (즉 팝업이 뜰때는 메뉴가 동작을 안한다)

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    if let app = UIApplication.shared.delegate as? AppDelegate {
        app.disableMenu()
    }
}

 

메뉴가 있는 뷰(동영상 재생뷰)가 열리면 menu를 enable해준다.

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    if let app = UIApplication.shared.delegate as? AppDelegate {
        app.enableMenu()
    }
}

 

enableMenu함수가 불리면 isRemoveMenu를 false로 주고 메뉴를 다시 빌드한다. (setNeedsRebuild)

 

disableMenu함수가 불리면 isRemoveMenu를 true로 주고 메뉴를 다시 빌드한다. (setNeedsRebuild)

 

그러면 buildMenu함수가 호출되고  isRemoveMenu값에 따라서 메뉴를 없앨지 메뉴를 다시 만들지 정한다.

//AppDelegate.swift
func enableMenu() {
#if targetEnvironment(macCatalyst)
    self.isRemoveMenu = false
    UIMenuSystem.main.setNeedsRebuild()
#endif
}

func disableMenu() {
#if targetEnvironment(macCatalyst)
    self.isRemoveMenu = true
    UIMenuSystem.main.setNeedsRebuild()
#endif
}

override func buildMenu(with builder: UIMenuBuilder) {
    if builder.system == .main {
        if isRemoveMenu {
            MenuController.removePlaybackMenu(with: builder)
        } else {
            menuController = MenuController(with: builder)
        }
    }
}

 

메뉴를 없애거나 다시 만드는 클래스

//MenuController.swift
class MenuController {
	init(with builder: UIMenuBuilder) {
        builder.insertSibling(MenuController.playbackMenu(), beforeMenu: .window)
    }
    
    class func removePlaybackMenu(with builder: UIMenuBuilder) {
        let id = self.playbackId()
        builder.remove(menu: UIMenu.Identifier.init(rawValue: id))
    }

    class func playbackMenu() -> UIMenu {
        let bundleID: String = AppUtils.getBundleId()
        let command1 =
            UIKeyCommand(title: MenuKeys.PLAY_STOP.rawValue.localized(),
                         image: nil,
                         action: #selector(PlayerViewController.playOrStopPlayer(_:)),
                         input: " ",
                         propertyList: nil)
        
        let tapValue = UserDefaults.settingByKey(key: SettingKey.TAP_FORWARD_BACKWARD.rawValue)
        let minSeconds: Double = Double(tapValue) ?? PlayerConstants.MIN_SEEK
        let minSecondsInt = Int(minSeconds)
        let forwardTitle = String(format: MenuKeys.STEP_FORWARD.rawValue.localized(), minSecondsInt)
        let playbackGroup = UIMenu(title: "",
                                     image: nil,
                                     identifier: UIMenu.Identifier("\(bundleID).menus.playbackSubMenu"),
                                     options: .displayInline,
                                     children: [command1])

        
        return UIMenu(title: MenuKeys.PLAYBACK.rawValue.localized(),
                      image: nil,
                      identifier: UIMenu.Identifier("\(bundleID).menu.playbacks"),
                      options: [],
                      children: [playbackGroup])
    }