access a UIButton within a rightBarButtonItem - swift

I have a navigationcontroller with a right UIBarButtonItem. I have added a UIButton to the BarButtonItem.
How can I get to the button at run time, if possible without using tags?

var myButton:UIButton?
var rightButton = navigationItem.rightBarButtonItems?.first
for view in rightButton.subviews() {
if view.iskindOfClass(UIButton) {
myButton = view
break
}
}

Related

How do you enable a UIButton in a different view controller?

I have a UIButton in MyViewController called MyButton:
let myButton: UIButton = {
let button = UIButton()
button.isEnabled = false
return button
}()
I can't seem to figure out how to enable this button in another view controller. I tried doing this:
class MyOtherViewController: UIViewController {
func enableButton() {
let upload = MyViewController()
upload.myButton.isEnabled = true
}
}
but the button was not enabled.
It seems super simple, but I can't figure it out... Thanks in advance!

Cannot display UIActivityIndicatorView

I meet a question. I am using following code to display UIActivityIndicatorView. My requirement is to be able to create an UIActivityIndicatorView and display it when I click the button with tag 1, if I click other buttons the UIActivityIndicatorView will be removed from the super view.
class ViewController: UIViewController {
lazy var acLoad:(UIActivityIndicatorView) = {
let myActivityIndicator = UIActivityIndicatorView(style: UIActivityIndicatorView.Style.white)
myActivityIndicator.center = view.center
myActivityIndicator.hidesWhenStopped = true
myActivityIndicator.startAnimating()
return myActivityIndicator
}()
//more code
#objc func btnAction(sender: UIButton){
switch sender.tag {
case 1:
print("created")
view.addSubview(acLoad)
acLoad.startAnimating()
default:
print("removed")
acLoad.stopAnimating()
acLoad.removeFromSuperview()
}
}
}
The above doesn't work, I can get the print log after click, but UIActivityIndicatorView doesn't display, any ideas?
It seems like your UIActivityIndicatorView might be misplaced (wrong frame value) - so it is not visible to you.
print("created")
view.addSubview(acLoad)
acLoad.startAnimating()
// Add this line in your button tap code
// It will tell you where it is placed inside your view
print(acLoad.frame)
If you find that it's frame is not where you want it to be, just fix your layout code and it will be where you expect it to be.
Another note - myActivityIndicator.hidesWhenStopped = true makes it automatically hide on stopAnimating() call. So you can add it only once, not remove-add every time.
Also check your view.backgroundColor vs acLoad style.

Button text not changing when called in viewController init

I'm trying to change the text of a UIButton based on values that are set in my viewController init.
So here's the init:
init(viewModel: ViewModel, stateMachine: StateMachine) {
self.viewModel = viewModel
self.stateMachine = stateMachine
super.init(nibName: nil, bundle: nil)
title = "TEST"
setInitialButtonText()
}
The button setting method:
private func setInitialButtonText() {
if viewModel.order.measurement.total != nil {
button.title = "Review"
} else {
button.title = "Check"
}
}
Required values are loaded in viewModel.
Now when I call this button method in this init, it has no effect. Yet when I call it in viewDidLoad, it works.
The button code is as follows:
lazy var button: UIButton = {
let button = UIButton(title: "Test", color: UIColor.green)
button.alpha = 1
return button
}()
init(#escaping buttonAction) {
super.init(frame: .zero)
translatesAutoresizingMaskIntoConstraints = false
stackView.addButtons([button])
button.pressedAction = buttonAction
}
When I put the method into init, the default initialised value of 'Test' shows on the button. However, when I print the button title from both init and viewDidLoad, first the viewDidLoad one is called and shows 'Test' and later the init one is called and shows the correct value. If this is called after viewDidLoad, why does it not reflect on the UI?
When I insert the method into viewDidLoad, the correct value is displayed...
Sure I'm missing something obvious here but any help would be appreciated.
UPDATE:
I printed from viewDidDisappear as well and the correct value is printing even when I call the method from init. So the property is being set but not displayed on the button...
Not sure whether that's the problem. But have you tried to set the title of the button by using button.setTitle("myTitle", for: .normal)?
None of the code above shows you actually adding the button to the view controller's view - without seeing more it's difficult to tell, but is it possible that you are also creating and adding the button in a xib, and assigning it to the button property? This would replace the button you have created in the lazy load.
Alternatively, is there a totally separate button that you are creating, but is never getting updated?
How does button get added to the view controller's view?
In the end I've added a new argument to the init as follows:
init(#escaping buttonAction, buttonTitle: String) {
self.buttonTitle = buttonTitle
super.init(frame: .zero)
translatesAutoresizingMaskIntoConstraints = false
stackView.addButtons([button])
button.pressedAction = buttonAction
}
Then in the button variable:
let button = I6Button(title: reviewFuelSheetButtonTitle, color: UIColor.i6.green)
And then finally in the viewController I added a didSet on the viewModel:
private var viewModel: ViewModel {
didSet {
setInitialButtonText()
}
}

Create action for button over modal segue. Unable to ctrl drag, Swift

Im trying to get a button to take me to a hyperlink, this button is located on an "About" page for my app. I have the following code which I know should do the job but I am unable to ctrl drag from the button and onto the "ViewController.Swift" file to create an action:
#IBOutlet weak var hyperLink: UIButton!
#IBAction func hyperLink(sender: UIButton!) {
if let url = NSURL(string: "http://www.google.com") {
UIApplication.sharedApplication().openURL(url)
}
}
Here is a pic of my storyboards, the button hyperlink I want to place is in the bottom left window:
New to Swift so any help is appreciated
Maybe, the View Controller in which you placed the button doesn't confirm to the custom class that you use.
Also, you can track where did you get your nil error above the terminal window:
You can set the button action programmertically as below.
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self
action:#selector(aMethod:)
Else try go last tab of the inspector panel and drag the relevant method/Action to element on object panel on the storyboard.

Non Standart UITabBarItem Action

I have UITabBarController with view
So on every TabBar I have ViewController. But on my center UITabBarItem I need to call something like modal UIViewController. And It should be like this
My UITabBarController class look like
class PlanetTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
self.tabBar.tintColor = kTintColor
var items = self.tabBar.items as! [UITabBarItem]
let centredTabBar:UITabBarItem = items[2]
self.tabBar.layer.borderWidth = 0.50
centredTabBar.image = ktabCentredBarImage
self.tabBar.layer.borderColor = UIColor.clearColor().CGColor
self.tabBar.layer.borderWidth = 0
self.tabBar.shadowImage = UIImage()
// self.tabBar.backgroundImage = ktabBarImage
self.tabBar.backgroundImage?.imageWithAlignmentRectInsets
print( UIDevice.currentDevice().modelName)
if( UIDevice.currentDevice().modelName != "iPhone 6" && UIDevice.currentDevice().modelName != "iPhone 6 Plus") {
self.tabBar.backgroundImage = ktabBarImage
}
if( UIDevice.currentDevice().modelName == "iPad 2" ) {
self.tabBar.backgroundImage = ktabBarImage
}
if let font = UIFont(name: "Avenir-Black", size: 10) {
let appearance = UITabBarItem.appearance()
let attributes = [NSFontAttributeName:font]
appearance.setTitleTextAttributes(attributes, forState: UIControlState.Normal)
}
}
}
I really have no idea how to override standart calling of UIViewController and call modal like this =) Please give me advice where I need to search
You can either place a UIButton in the same area as the UITabBarItem and fire an action or you can simply fire an action when the selectedSegmentIndex changes("value changed" in IB) for the UITabBar after creating a center UITabBarItem. The design choice is yours. The first step is to understand the objects you're working with. It would probably be easier to just add a button, center aligned, over top of the standard UITabBar at the bottom so you don't deal with a custom UITabBarController to handle that non-uniform image above the tab bar.
Or just create your own TabBar down there. It's very simply to setup a few UIButtons or UIViews next to one another that don't have a static height such as a UITabBarController which would allow for that center object.
UITabBarController
UIViewController
Presenting a ViewController