专业java、php、iOS、C++、网页设计、平面设计、网络营销、游戏开发、前端与移动开发培训机构
添加撰写按钮
系统tabBar满足不了需求,这时候我们需要自定义UITabBar
- 我们发现UITabBarController里面的tabBar是一个只读计算型属性,不能直接进行修改:
@available(iOS 3.0, *) var tabBar: UITabBar { get } // Provided for -[UIActionSheet showFromTabBar:]. Attempting to modify the contents of the tab bar directly will throw an exception.
- 然而我们只想用代码来替换现UITabBarController里面的tabBar.这时候可以用
KVC
来进行. 自定义
HMMainTabBar
:
UITabBar
class HMMainTabBar: UITabBar { override func layoutSubviews() { super.layoutSubviews() print("layoutSubviews") } }
override func viewDidLoad() { super.viewDidLoad() // 自定义tabbar,是只读的,不能直接使用 = 进行赋值 // KVC 进行替换 let newTabBar = HMMainTabBar() setValue(newTabBar, forKey: "tabBar") // 添加4个子控制器 addChildViewControllers() }
- 我们发现UITabBarController里面的tabBar是一个只读计算型属性,不能直接进行修改:
完善
HMMainTabBar
class HMMainTabBar: UITabBar { //: 懒加载撰写按钮 lazy var composeButton: UIButton = { let button = UIButton() // 添加背景图片 button.setBackgroundImage(UIImage(named: "tabbar_compose_button"), for: UIControlState.normal) button.setBackgroundImage(UIImage(named: "tabbar_compose_button_highlighted"), for: UIControlState.highlighted) button.setImage(UIImage(named: "tabbar_compose_icon_add"), for: UIControlState.normal) button.setImage(UIImage(named: "tabbar_compose_icon_add_highlighted"), for: UIControlState.highlighted) self.addSubview(button) return button }() // 定义tabBar按钮总数 = 5 private let buttonCount = 5 override func layoutSubviews() { super.layoutSubviews() // 计算每个tabBarItem的宽度 let width = bounds.width / CGFloat(buttonCount) // 创建每个tabBarItem的frame let frame = CGRect(x: 0, y: 0, width: width, height: bounds.height) var index = 0 for view in subviews { // 判断是否是 UITabBarButton let cls = NSClassFromString("UITabBarButton") if view.isKind(of: cls!) { view.frame = CGRect(x: CGFloat(index) * width, y: 0, width: width, height: frame.height) //: 留出第2个位置给撰写按钮 index += 1 if index == 2 { index += 1 } } } // 设置撰写按钮到中间位置 composeButton.frame = CGRect(x: 2 * width, y: 0, width: width, height: frame.height) } }
撰写按钮点击事件
1.在
HMMainTabBar
中添加composeClosure
属性, composeClosure的类型为:(() -> ())?
不需要参数,没有返回值的闭包
.class HMMainTabBar: UITabBar { // 属性 /// 按钮点击的闭包 (() -> ())? 是一个可选 var composeClosure: (() -> ())? }
2.在
HMMainTabbarController
控制器的viewDidLoad
方法里面准备闭包override func viewDidLoad() { super.viewDidLoad() // 自定义tabbar,是只读的,不能直接使用 = 进行赋值 // KVC 进行替换 let mainTabBar = HMMainTabBar() setValue(mainTabBar, forKey: "tabBar") // 准备闭包 mainTabBar.composeClosure = { () -> () in print("撰写按钮被点击了") } }
- 3.在
HMMainTabBar
中给按钮添加点击事件// 撰写按钮添加点击事件 button.addTarget(self, action: #selector(composeClick), for: UIControlEvents.touchUpInside)
- 4.在撰写微博按钮点击事件中调用闭包
/// 撰写微博按钮被点击 func composeClick() { // UIView是不能直接弹出控制器的 // 调用闭包, ? 如果闭包没有值,就不执行 composeClosure?() }