I have a custom uiview (call it navBarMenu) with five buttons as subviews. I added this navBarMenu to the navigationbar's titleView. The navBarMenu has its own class and nib file where the buttons are defined as iboutlets. How can I add targets so that when I click the button in the navBarMenu it will trigger a function in my viewcontroller that is embedded in the navigation controller?
Using the method: navBarMenu.Button1.addTarget(self, action: "Button1Tapped:", forControlEvents: UIControlEvents.TouchUpInside)
does not work and I get an error that it unexpectedly found nil while unwrapping an Optional value.
Edit: Here is the code for my view controller and my custom view.
class MyCustomView: UIView {
var view: UIView!
var nibName: String = "MyCustomView"
@IBOutlet weak var Button1: UIButton!
@IBOutlet weak var Button2: UIButton!
@IBOutlet weak var Button3: UIButton!
@IBOutlet weak var Button4: UIButton!
@IBOutlet weak var Button5: UIButton!
var Button1Text: String? {
get {
return Button1.titleLabel?.text
}
set(Button1Text) {
Button1.setTitle(Button1Text, forState: UIControlState.Normal)
}
}
var Button2Text: String? {
get {
return Button2.titleLabel?.text
}
set(Button2Text) {
Button2.setTitle(Button2Text, forState: UIControlState.Normal)
}
}
var Button3Text: String? {
get {
return Button3.titleLabel?.text
}
set(Button3Text) {
Button3.setTitle(Button3Text, forState: UIControlState.Normal)
}
}
var Button4Text: String? {
get {
return Button4.titleLabel?.text
}
set(Button4Text) {
Button4.setTitle(ButtonText4, forState: UIControlState.Normal)
}
}
var Button5Text: String? {
get {
return Button5.titleLabel?.text
}
set(Button5Text) {
Button5.setTitle(ButtonText5, forState: UIControlState.Normal)
}
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
println("view is setup")
}
convenience init(controller: UIViewController) {
var frameForNavBar: CGRect = CGRect(x: 0.0, y: 0.0, width: 548.0, height: 33.0)
self.init(frame: frameForNavBar)
Button1.addTarget(controller, action: "Button1Tapped:", forControlEvents: UIControlEvents.TouchUpInside)
Button2.addTarget(controller, action: "Button2Tapped:", forControlEvents: UIControlEvents.TouchUpInside)
Button3.addTarget(controller, action: "Button3Tapped:", forControlEvents: UIControlEvents.TouchUpInside)
Button4.addTarget(controller, action: "Button4Tapped:", forControlEvents: UIControlEvents.TouchUpInside)
Button5.addTarget(controller, action: "Button5Tapped:", forControlEvents: UIControlEvents.TouchUpInside)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func setup() {
view = loadViewFromNib()
view.frame = bounds
addSubview(view)
}
func loadViewFromNib() -> UIView {
let bundle = NSBundle(forClass: self.dynamicType)
let nib = UINib(nibName: nibName, bundle: bundle)
let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
return view
}
}
class MyViewController: UIViewController, UINavigationBarDelegate {
@IBOutlet weak var webView: UIWebView!
func Button1Tapped(sender: AnyObject) {
println(__FUNCTION__)
}
func Button2Tapped(sender: AnyObject) {
println(__FUNCTION__)
}
func Button3Tapped(sender: AnyObject) {
println(__FUNCTION__)
}
func Button4Tapped(sender: AnyObject) {
println(__FUNCTION__)
}
func Button5Tapped(sender: AnyObject) {
println(__FUNCTION__)
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: "MyViewController", bundle: nil)
}
convenience init() {
self.init(nibName: "MyViewController", bundle: nil)
tabBarItem.title = "MyVC"
tabBarItem.image = UIImage(named: "MyImage")
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
let navBarMenu = MyCustomView(controller: self)
positionForBar(navigationController!.navigationBar)
self.navigationItem.titleView = navBarMenu
self.navigationController?.navigationBar.translucent = false
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func loadWebPage() {
}
func positionForBar(bar: UIBarPositioning) -> UIBarPosition {
return UIBarPosition.TopAttached
}
}
When you initialize your customView you can pass the UIViewController parameter and then add target for your button to it.
let myCustomView = MyCustomViewClass(self)
And in your MyCustomViewClass you can use:
init (controller: UIViewController) {
// use controller, not self
button.addTarget(controller, action: "Button1Tapped:", forControlEvents: UIControlEvents.TouchUpInside)
}