ios - Swift:将 UIButton 转换为 UIBarButtonItem,真的需要这么复杂吗?

标签 ios swift swift3 uinavigationbar uibarbuttonitem

我已经在 UIButton 上编写了一个扩展,它将 UIButton 转换为 UIBarButtonItem

我尝试使用 init(customView on UIBarButtonItem 传递我的按钮来实现最简单的解决方案,如下所示:

lazy var myButton: UIButton = { 
    let button = UIButton(type: .custom)
    // setting up button here...
    return button
}()

let barButtonItem = UIBarButtonItem(customView: myButton)

但我有几个约束问题。实际上我不只是想在导航栏中放一个按钮,而是三个项目。所以我尝试将我的三个按钮放入 UIStackView 中,然后设置 navigationItem.rightBarButtonItem = UIBarButtonItem(customView: stackView) 这在 iOS 10 上非常有效.但在 iOS 9 上,按钮的位置不起作用。

无论如何,我求助于使用 UIBarButtonItem 而不是 UIButton,但我不想为 iOS 9 创建 UIBarButtonUIButton 用于 iOS 10。所以我写了一个扩展,从 UIButton 创建 UIBarButtonItem。启用此代码。

处理 iOS 9 和 iOS 10 的解决方案

func setupNavigationBar() {
    if #available(iOS 10.0, *) {
        let stackView: UIStackView = [.views(buttons)] //syntax enabled by framework `ViewComposer`: github.com/Sajjon/ViewComposer
        navigationItem.rightBarButtonItem = UIBarButtonItem(customView: stackView)
    } else {
        navigationItem.rightBarButtonItems = buttons.reversed().flatMap { $0.barButtonItem } // syntax enabled by extension below
    }
}

这是我的扩展代码。

扩展 UIButton

extension UIButton {

    var barButtonItem: UIBarButtonItem? {
        return barButtonItem()
    }

    func barButtonItem(
        style: UIBarButtonItemStyle = .plain,
        state: UIControlState = .normal,
        controlEvent: UIControlEvents = .primaryActionTriggered
        ) -> UIBarButtonItem? {

        guard
            let target = allTargets.first,
            let selectorName = actions(forTarget: target, forControlEvent: controlEvent)?.first,
            case let image = image(for: state), case let title = title(for: state),
            (image != nil || title != nil)
            else { return nil }

        let action = NSSelectorFromString(selectorName)

        if let image = image {
            return UIBarButtonItem(image: image, style: style, target: target, action: action)
        }

        if let title = title {
            return UIBarButtonItem(title: title, style: style, target: target, action: action)
        }

        return nil //should not happen
    }
}

问题 1:为什么在 UIStackView 中定位 UIButtons 在 iOS 9 上不起作用?

问题 2:我的扩展是否过于复杂?还是不安全?

最佳答案

扩展可以简化

extension UIButton {
    func toBarButtonItem() -> UIBarButtonItem? {
        return UIBarButtonItem(customView: self)
    }
}

关于ios - Swift:将 UIButton 转换为 UIBarButtonItem,真的需要这么复杂吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44764132/

相关文章:

ios - 从一个 UIButton 创建多个 segues 到同一个 View Controller 或另一个

ios - 为什么在呈现 View Controller 后 UIView 从层次结构中删除?

ios - 两个不同的tableview xCode之间的冲突

swift - 如何异步使用 Firebase?数据库读取给出奇怪的结果

ios - iOS 7:从json响应中选择特定对象

swift - 将具有嵌套自定义类的自定义类数组存储到 standardUserDefaults

ios - 在不同的滑动 View 之间传递 UIPageViewController 中的数据

ios - 我的 IF 语句只会运行一个条件 - iOS Swift

ios - swift 3 : Custom Cell not displaying data

swift - 使用 "open"和 "public"