在ViewController中的属性闭包中定义UIBarButtonItems

时间:2017-11-15 15:32:28

标签: ios swift

我想通过闭包在视图控制器的属性中设置一个UIBarButtonItems数组。

所以不要在viewDidLoad中执行此操作:

let b1 = UIBarButtonItem(title: "MoveUp", style: .plain, target: self, action: #selector(b1Tapped(sender:)))
let b2 = UIBarButtonItem(title: "b2", style: .plain, target: self, action: #selector(b2Tapped(sender:)))
let b3 = UIBarButtonItem(title: "b3", style: .plain, target: self, action: #selector(b3Tapped(sender:)))
navigationItem.rightBarButtonItems = [b3, b2, b1]

我这样做了:

lazy var bbItems: [UIBarButtonItem] = {
    let b1 = UIBarButtonItem(title: "MoveUp", style: .plain, target: self, action: #selector(b1Tapped(sender:)))
    let b2 = UIBarButtonItem(title: "b2", style: .plain, target: self, action: #selector(b2Tapped(sender:)))
    let b3 = UIBarButtonItem(title: "b3", style: .plain, target: self, action: #selector(b3Tapped(sender:)))

    return  [b3, b2, b1]
}()

然后在viewDidLoad

navigationItem.rightBarButtonItems = bbItems

我必须让它成为一个懒惰的var来执行连接到按钮的功能。当它只是一个常规变量时它没有执行它。

这样做是否有任何缺点。还有更好的方法吗?

由于

1 个答案:

答案 0 :(得分:0)

您可以通过参数将目标传递给闭包。我使用Protocol来定义一个具有目标函数的抽象类型。

在swift 4中会是这样的。

// it should be @objc because selectors need functions that are visibile to Objective-C
@objc protocol NavigaitonBarConfigurable: class {
    func b1Tapped(_ sender: UIBarButtonItem)
    func b2Tapped(_ sender: UIBarButtonItem)
    func b3Tapped(_ sender: UIBarButtonItem)
}

/// create UIBarButtonItems
func createNavigationBarButtons(target: NavigaitonBarConfigurable) ->  [UIBarButtonItem] {
    let b1 = UIBarButtonItem(title: "MoveUp",
                             style: .plain,
                             target: target,
                             action: #selector(NavigaitonBarConfigurable.b1Tapped(_:)))
    let b2 = UIBarButtonItem(title: "b2",
                             style: .plain,
                             target: target,
                             action: #selector(NavigaitonBarConfigurable.b2Tapped(_:)))
    let b3 = UIBarButtonItem(title: "b3",
                             style: .plain,
                             target: target,
                             action: #selector(NavigaitonBarConfigurable.b3Tapped(_:)))
    return [b1, b2, b3]
}

class ViewController: UIViewController {
    // pass the function for creating buttons with target as self (self is NavigaitonBarConfigurable)
    lazy var bbItems: [UIBarButtonItem] = createNavigationBarButtons(target: self)

    override func viewDidLoad() {
        super.viewDidLoad()
        navigationItem.setRightBarButtonItems(self.bbItems, animated: false)
    }
}

extension ViewController: NavigaitonBarConfigurable {
    func b1Tapped(_ sender: UIBarButtonItem) {
        print("b1")
    }

    func b2Tapped(_ sender: UIBarButtonItem) {
        print("b2")
    }

    func b3Tapped(_ sender: UIBarButtonItem) {
        print("b3")
    }
}