Swapping bar button items - swift

I'd like to swap a bar button item, depending on a UISegmentControl which I thought would be fairly straight forward.
My initial plan was:
Create an IBAction for when the segment changes
Work out which segment we are on
Hide the appropriate button
The code was something like this
#IBAction func segmentChanged(sender: UISegmentedControl) {
UIView.animateWithDuration(0.25) { () -> Void in
if(sender.selectedSegmentIndex == 0) {
barButtonA.hidden = true
barButtonB.hidden = false
} else {
barButtonA.hidden = false
barButtonB.hidden = true
}
}
}
That hid the right button as expected, but oddly, the space where the button was still remained, so it looked really strange.
Next I saw that in the interface builder there is a parent container (UIBarButtonItems) for each of the buttons. I'm not sure why they're needed, but I hooked them up via IBOutlets so I could hide/show them in the function, but that didn't work either as they don't have a hidden property.
Finally, I tried to use those new outlets with following code:
#IBAction func segmentChanged(sender: UISegmentedControl) {
UIView.animateWithDuration(0.25) { () -> Void in
if(sender.selectedSegmentIndex == 0) {
self.navigationItem.rightBarButtonItem = self.barButtonItemA
} else {
self.navigationItem.rightBarButtonItem = self.barButtonItemB
}
}
}
But no luck! Here, it just seems to animate swapping the two button positions/order, rather than actually removing either one.
What am I doing wrong? Thanks!

Yo should combine the two function you have.
So swap them and change the hidden state.
Update:
Did you tried to first delete the navigation.barbutton.
self.navigationItem.rightBarButtonItem = nil

Related

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.

How do I make a button add one view at a time?

I'm practicing creating an app that has 3 views. Each view has a button to hide itself. Now, I added a button outside the views to re-add them after I hide them, but, when i remove the views and I press it, it shows me all of the three views. I want it to add one view at a time (without removing the other views). What can I do?
This is my code, I was even thinking about adding multiple add buttons but it wouldn't be clear.
#IBAction func addViewButton(_ sender: Any) {
view1.isHidden = false
view2.isHidden = false
view3.isHidden = false
}
Declare a variable like currentVisibleViews in your ViewController, and lets say at first there is only first one is visible so we start off the number as 1, and also add your views to an array to control easier:
var currentVisibleViews = 1
var viewArray = [UIView]()
In viewDidLoad, add your views to viewArray:
view1.isHidden = false
view2.isHidden = true
view3.isHidden = true
viewArray.append(view1)
viewArray.append(view2)
viewArray.append(view3)
Then in your button:
#IBAction func addViewButton(_ sender: Any) {
if currentVisibleViews > 2 {
viewArray.forEach { (view) in
view.isHidden = true
}
currentVisibleViews = 0
} else {
viewArray[currentVisibleViews].isHidden = false
currentVisibleViews += 1
}
}
Code above works as this:
First all views are visible
First tap will hide all views
Then each tap will make a view visible
Go to step 2 (once all views are visible)
By this way, you can only have one function to control all your views, it doesnt have to be IBAction anymore, it can be just a method of your ViewController

Hide add button

I am trying to have a button, so the user can hide the add banner if they want to, this works but when the add banner is not displaying I want the button to also be hidden. So I added the following code, but as soon as I did so, the button stopped working. Any ideas as to why?
thank you!
override func viewDidLoad() {
super.viewDidLoad()
if Banner.hidden == false{
hideAdd.hidden = false
} else {
hideAdd.hidden = true
}
The following is the code I used to hide the banner
#IBAction func HideAddButton(sender: AnyObject) {
Banner.hidden = true
}
The easiest way to hide and unhide objects on a MainStoryboard is to change the alpha to 0 in the attributes inspector. Then when you want it to appear you can just change the alpha in your code to 1 when you want it to appear in ViewController.swift. Or Vice Versa.

(swift) Anyone can help me to make bulk change to those buttons?

here is the screenshot
when user get into this page, I want to change the background of those button.
for example, when the level of user is 6, I want to change the top 6 background of buttons to a blue picture as first button. I don't wanna write a code one by one, so please help me to write a function, Thank you very much!
You can add you buttons to the array in order of increasing level and do something like this:
var buttons: [UIButton] // array of your buttons, next you need to init it
...
func setColorForUserLevel(userLevel: Int) {
if userLevel > buttons.count {
return
} else {
for i in 0...userLevel - 1 {
buttons[i].backgroundColor = UIColor.blueColor()
}
}
}
I create simple example project to show how to use it:
I have outlets with UIButton! type and buttons object in code:
And i test setColorForUserLevel function in viewDidLoad method:
override func viewDidLoad() {
super.viewDidLoad()
buttons = [button1, button2, button3]
setColorForUserLevel(2)
}

Cannot manually set the highlighted state of a UIButton in an IBAction method

Inside my ViewController, I have two IBOutlets signUpButton and memberButton, and both buttons are linked to same signUpOrMemberButtonPressed() IBAction func. I am trying to set highlighted property to these 2 buttons so I can do subsequent work accordingly inside my submitPressed() IBAction func. But I noticed odd behavior between signUpOrMemberButtonPressed() and submitPressed() IBActions. After tapping on either signUpButton or memberButton, the button was highlighted inside my signUpOrMemberButtonPressed(), but by the time it executed submitPressed(), debug showed it's not highlighted. Here is my signUpOrMemberButtonPressed():
#IBAction func signUpOrMemberButtonPressed(sender: AnyObject) {
var button = sender as UIButton
button.highlighted = true
if signUpButton.highlighted {
memberButton.highlighted = false
} else {
signUpButton.highlighted = false
}
if (signUpButton.highlighted) {
println("signUpButton is highlighted inside 1st button")
} else if (memberButton.highlighted) {
println("memberButton is highlighted inside 1st button")
} else {
println("nothing is highlighted inside 1st button")
}
}
My submitPressed function:
#IBAction func submitPressed(sender: AnyObject) {
if (signUpButton.highlighted) { println("signUpButton is highlighted inside 2st button") }
else if (memberButton.highlighted) { println("memberButton is highlighted inside 2st button") }
else { println("nothing is highlighted inside 2nd button")
}
When run my app, I tapped on memberButton and then tapped on submit button. Here is the log output:
memberButton is highlighted inside 1st button
nothing is highlighted inside 2nd button
Nothing was set to run between these two func calls.
What is happening here is that the button is "un-highlighting" itself (after you manually set highlighted = true).
From the documentation of the highlighted property:
UIControl automatically sets and clears this state automatically when
a touch enters and exits during tracking and when there is a touch up.
You can set the highlighted state manually but you would have to do it after the UIButton unsets the highlighted state. You would have to do this on the next run loop which you can do by using dispatch_async.
The following should work:
var button = sender as UIButton
dispatch_async(dispatch_get_main_queue()) {
self.memberButton.highlighted = button == self.memberButton
self.signUpButton.highlighted = button == self.signUpButton
}