You are right, I was using a private APIs, and it will not pass the apple app store review process.
What I was looking for was a way to hide the UIBarButtonItem under some circustances.
Wrong code:
import UIKit
struct User{
let name : String
}
class WrongViewController: UIViewController {
@IBOutlet weak var addBarButtomItem: UIBarButtonItem!
@IBAction func add(_ sender: Any) {
}
@IBAction func createUser(_ sender: Any) {
user = User(name: "John")
}
var user : User?{
didSet{
// iOS 11 fatal error: unexpectedly found nil while unwrapping an Optional value
let addBarButtomItemView: UIView = addBarButtomItem.value(forKey: "view") as! UIView
if user != nil {
addBarButtomItem.isEnabled = true
addBarButtomItemView.isHidden = false
} else {
addBarButtomItem.isEnabled = false
addBarButtomItemView.isHidden = true
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
user = nil
}
}
I finally solve the issue using an strong IBOutlet, instead of weak, and placing it in the ViewController instead of in the Navigation Item and adding or removing it to the Navigation Item instead of hidding it.
Right code:
import UIKit
struct User{
let name : String
}
class RightViewController: UIViewController {
@IBOutlet var addBarButtomItem: UIBarButtonItem!
@IBAction func add(_ sender: Any) {
}
@IBAction func createUser(_ sender: Any) {
user = User(name: "John")
}
var user : User?{
didSet{
if user != nil {
navigationItem.rightBarButtonItem = addBarButtomItem
} else {
navigationItem.rightBarButtonItem = nil
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
user = nil
}
}
I found also another way using a weak IBOutlet, instead of get a reference to the view of the UIBarButtonItem and hide it, using the tintColor property of the UIBarButtonItem, as follow:
import UIKit
struct User{
let name : String
}
class RightViewController: UIViewController {
@IBOutlet weak var addBarButtomItem: UIBarButtonItem!
@IBAction func add(_ sender: Any) {
}
@IBAction func createUser(_ sender: Any) {
user = User(name: "John")
}
var user : User?{
didSet{
if user != nil {
addBarButtomItem.isEnabled = true
addBarButtomItem.tintColor = nil // set a UIBarbutton back to the default tint color
} else {
addBarButtomItem.isEnabled = false
addBarButtomItem.tintColor = .clear
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
user = nil
}
}