如何在UIViewControllerRepresentable结构体中创建可响应点击的UIBarButtonItem
问题根因
你的代码存在两个核心问题导致点击无响应:
- 创建
UIBarButtonItem时target参数传了nil,系统无法找到响应点击事件的对象 - 你单独定义的
navigationActions类没有被实例化和强持有,即使指定了target也会因为实例被释放导致无法触发方法
没必要单独创建存放@objc方法的类,直接把交互逻辑放到已有的Coordinator中即可,这也是UIViewControllerRepresentable标准的交互处理方式。
解决方案
步骤1:修改Coordinator类,新增菜单点击处理方法
// Search Bar delegate class Coordinator: NSObject, UISearchBarDelegate { var parent : CustomNavigationBar init(parent: CustomNavigationBar) { self.parent = parent } func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { self.parent.onSearch(searchText) } func searchBarCancelButtonClicked(_ searchBar: UISearchBar) { self.parent.onCancel() } // 新增菜单点击响应方法 @objc func hamburgerTapped(_ sender : UIBarButtonItem) { print("hamburger tapped") // 调用外部传入的侧边栏弹出回调 self.parent.didTapMenu() } }
步骤2:修改菜单按钮的初始化代码
把target指向context中的coordinator实例,action替换为Coordinator中的对应方法:
// 替换原有的menuButton创建代码 let menuButton = UIBarButtonItem(image: UIImage(named: "hamburgerMenu"), style: .plain, target: context.coordinator, action: #selector(Coordinator.hamburgerTapped(_:))) childView.navigationItem.leftBarButtonItem = menuButton
步骤3:删除冗余代码
你单独定义的navigationActions类已经没用了,可以直接删掉。
额外注意事项
原来的hamburgerTapped方法参数定义为UIButton属于类型错误,UIBarButtonItem触发的action的sender类型是UIBarButtonItem,修改后更符合规范,不会出现隐式类型转换的潜在问题。
修改完成后只要你在使用CustomNavigationBar时正确实现了didTapMenu闭包的侧边栏弹出逻辑,即可正常运行。
内容的提问来源于stack exchange,提问作者iOSDevManni
相关产品推荐
相关产品推荐

