IBOutletCollection collection - ios

I'm looking for a way to change background color only for buttons that have the same text. So I created (at this time only 2) IBOutletCollections and 1 IBAction to test. But I have 27 different button numbers to code... or do I need to create 27 Outlet Collections and 27 Actions?
class SecondViewController: UIViewController {
#IBOutlet var button1color: [UIButton]!
#IBOutlet var button2color: [UIButton]!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func bouton1(_ sender: UIButton) {
for button in self.button1color {
if button.backgroundColor == nil {
button.backgroundColor = UIColor(displayP3Red: 1, green: 1, blue: 0.5, alpha: 0.8)
} else {
button.backgroundColor = nil
}
}
}
Is there a way to create a function to avoid typing 27 times the same code for each case?
For more informations, feel free to ask me!
Thank you for your help.

I'm looking for a way to change background color only for buttons that have the same text
I understand it like this: You need collection of buttons and when some button from this collection is pressed, you want to change color for all buttons from collection which have the same text (title when we're speaking about UIButton)
So you can have just one collection for all buttons. Link them to this collection
#IBOutlet var buttons: [UIButton]!
and also you can have just one action for all buttons. Also link them to this action. Then when button is pressed, change backgroundColor of button which has the same title as button which's been pressed
#IBAction func buttonPressed(_ sender: UIButton) {
for button in buttons where button.currentTitle == sender.currentTitle {
button.backgroundColor = UIColor(displayP3Red: 1, green: 1, blue: 0.5, alpha: 0.8)
}
}

Related

Question about delegate and protocol in swift (with example)

I am trying to work with delegate and protocol but met a problem.
I created 2 buttons on one ViewController and created 1 imageView in another ShowViewController. The color of the imageView will change according to which button is pressed.
ViewController.swift
import UIKit
protocol getColorProtocol {
func getColor(color:String?)
}
class ViewController: UIViewController {
var color: String?
var delegate:getColorProtocol?
#IBAction func blueButtonPressed(_ sender: Any) {
color = "blue"
delegate?.getColor(color: color)
}
#IBAction func redButtonPressed(_ sender: Any) {
color = "red"
delegate?.getColor(color: color)
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
ShowViewController.swift
import UIKit
class ShowViewController: UIViewController, getColorProtocol {
var viewOne = ViewController()
#IBOutlet weak var colorView: UIImageView!
func getColor(color: String?) {
print("color is \(color!)")
if color == "red"{
colorView.backgroundColor = UIColor(displayP3Red: 255/255, green: 0/255, blue: 0/255, alpha: 1)
}
else if color == "blue" {
colorView.backgroundColor = UIColor(displayP3Red: 0/255, green: 0/255, blue: 255/255, alpha: 1)
}
}
override func viewDidLoad() {
super.viewDidLoad()
viewOne.delegate = self
}
}
press here to view the storyboard!
You may check my storyboard above.
Currently, it has no error but it cannot call the getColor function. I am wondering if the problem is coming from the delegate?.getColor(color: color) statement.
Any ideas?
First of all, in your case, you don't need to use delegate pattern
Your ViewController connect directly to ShowViewController through segue
You can use prepareForSegue instead
Secondly, I don't think you understand how delegate pattern works,
Inside ShowViewController, you're create a new ViewController called viewOne, it isn't the original ViewController so that's why your code doesn't work as expected
As I mentioned above, you should use segue
first, go to the storyboard setup your segue identifier. Then, inside your ViewController
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier == "goToShowVC") {
//your code here
}
}
You don't need a delegate for this, but just prepare for segue. I see that you have two segues set up already, so in your viewcontroller, assuming your segues are called "blue" and "red" in your storyboard, you could add:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destinationVC = segue.destination as? ShowViewController {
if segue.identifier == "blue" {
destinationVC.color = UIColor.blue
} else if segue.identifier == “red” {
destinationVC.color = UIColor.red
}
}
}
then you would want to add a color variable to manipulate in your showviewcontroller. For example:
var color = UIColor.white
colorview.backgroundcolor = color

Selecting and deselecting collection of buttons

I have three buttons named One, Two, and Three, and a function buttonPressed for collection of those three buttons as follows.
var btnTag = [Int]()
#IBAction func buttonPressed(_ sender: UIButton) {
guard let button = sender as UIButton? else { return }
if(btnTag.contains((sender as AnyObject).tag!))
{
if let index = btnTag.index(of: (sender as AnyObject).tag!)
{
btnTag.remove(at: index)
}
}
else
{
btnTag.append((sender as AnyObject).tag!)
}
if !button.isSelected {
button.isSelected = true
button.setTitleColor(.red, for: .normal)
}
else
{
button.isSelected = false
button.setTitleColor(.white, for: .normal)
}
}
I like to change color of button as red when clicked and then when I click other button the previous button color as white. So if I press One, I want One to be red and then when I pres Two, I want Two to be red and One as white. I did the above but it is allowing multiple selection and not able to deselect previous changes. How do I solve this?
You can simply create collection of UIButton. After that assign tag of all three UIButton from Storyboard.
#IBOutlet var buttons: [UIButton]!
Use above collection and connect all the button with Outlet. also connect below action with all buttons.
#IBAction func buttonPressed(_ sender: UIButton) {
buttons.forEach { $0.isSelected = false
$0.setTitleColor(.white, for: .normal)
}
buttons[sender.tag].setTitleColor(.red, for: .normal)
buttons[sender.tag].isSelected = true
}
Since you are highlighting only one button at the moment, you don't need tag array instead the reference to all buttons.
//Let say these are my button refrence
#IBOutlet weak var button1: UIButton!
#IBOutlet weak var button2: UIButton!
#IBOutlet weak var button3: UIButton!
All of those buttons are targeting same method
#IBAction func buttonPressed(_ sender: UIButton) {
//clear all button selected state
clearSelectedState()
//select the button that was clicked
sender.isSelected = true
sender.setTitleColor(.red, for: .normal)
}
func clearSelectedState() {
button1.isSelected = false
button1.setTitleColor(.white, for: .normal)
.... proceed to do for others
}
Now in clearSelectedState method I don't like the repetition of code. So what we can do is put the reference in array and do something like
///this can be replaced in clear state method
[button1, button2, button3,...].forEach {
$0.isSelected = false
$0.setTitleColor(.white, for: .normal)
}

Change the toolbar color

It is working for navigationBar:
var colour = UIColor.red
self.navigationController?.navigationBar.tintColor = colour
But do not work for toolbar:
self.navigationController?.toolbar.tintColor = colour
I searched the internet and stack overflow. No answer is workable for me.
Some people said:
self.toolbar.barTintColor = UIColor.redColor()
It is also not working for me. (value of type 'thisView' has no member 'toolbar')
I want to edit the toolbar color in coding. No change in the storyboard setting. Thanks.
EDIT:
I am working on adding a toolbar under the webview. Like go back, stop, reload.
//
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var webView: UIWebView!
var colour = UIColor.red
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.tintColor = colour
// problem in here ..........................
self.navigationController?.toolbar.tintColor = UIColor.black
let URL = NSURL(string: "https://www.apple.com")
webView.loadRequest(NSURLRequest(url: URL! as URL) as URLRequest)
}
#IBAction func backButton(_ sender: AnyObject) {
webView.goBack()
}
#IBAction func nextButton(_ sender: AnyObject) {
webView.goForward()
}
#IBAction func refreshButton(_ sender: AnyObject) {
webView.reload()
}
#IBAction func stopbutton(_ sender: AnyObject) {
webView.stopLoading()
}
}
If you've just got a toolbar that is on a ViewController in Your Storyboard all you need to do is add an IBOutlet to your View Controller and connect the toolbar in the storyboard to that outlet. This code goes in your ViewController
#IBOutlet var toolbar: UIToolbar?
Then, in the storyboard, hold the control button and click drag from View Controller (in the left sidebar) to your toolbar. This will create a connection between the toolbar in the storyboard to the toolbar var in your code. After that connection is made all you need to do is set the barTintColor on that toolbar variable like so:
self.toolbar.barTintColor = UIColor.blue
I wrote this function a few days ago to kinda workaround the fact that you can't change the color.
func setStatusBarColor(){
let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.size.width, height: 20.0))
view.backgroundColor = UIColor(red: 81/255, green: 184/255, blue: 222/255, alpha: 1)
self.view.addSubview(view)
}
Also make sure to set the statusbar to .lightContent
UIApplication.sharedApplication().statusBarStyle = .LightContent

Swift Button Background Image not appearing?

I have some very simple code to just programmatically set a button's background image to something but when the simulator runs it shows nothing. On the storyboard it shows that the image is present however, and again nothing shows.
class ViewController: UIViewController {
#IBOutlet weak var LetUsOutlet: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
let backgroundColor = UIColor(red: 0, green: 255, blue: 247, alpha: 1)
self.view.backgroundColor = backgroundColor
let backgroundButtonImage = UIImage(named: "round rectangle button.png") as UIImage?
self.LetUsOutlet.setImage(backgroundButtonImage, for: .normal)
}
#IBAction func LetUsCreateMeal(_ sender: UIButton) {
}
#IBAction func CreateYourOwn(_ sender: UIButton) {
}
#IBAction func BrowseItems(_ sender: UIButton) {
}
#IBAction func ViewYourMeals(_ sender: UIButton) {
}
}
This is the simple code that I have so I am not sure why it isn't working properly. Below is my storyboard.
http://imgur.com/gallery/c5EWW
The first button is where I try to programatically set the background, and the other 3 are when I just set the background image property within the storyboard.
This is what happens when it runs, showing that all background images are empty.
http://imgur.com/gallery/urM25
Any help is appreciated.
EDIT: I seemed to have the image stored in the wrong place, I put it in a separate folder and not in the xassets folder.
To change button background image you should use
LetUsOutlet.setBackgroundImage(UIImage(named:"round rectangle button.png"), forState: UIControlState.Normal)
I mocked up an example - seemed to work okay for me. I suggest you check your button's constraints in IB
change this line
let backgroundButtonImage = UIImage(named: "round rectangle button.png") as UIImage?
to this line
let backgroundButtonImage = UIImage(named: "round rectangle button")
and this line
self.LetUsOutlet.setImage(backgroundButtonImage, for: .normal)
to this
self.LetUsOutlet.setBackgroundImage(backgroundButtonImage, for: .normal)

Swift - UIToolbar item selected state

I have this toolbar in my navigation controller. Now what I am trying to do is when the user selects an item (UIBarButtonItem) in my toolbar, have that item highlighted with a background colour until either the user deselects the item or selects another item. How would I do this?
Here are my selector methods for each item of the toolbar, I connected them via storyboard:
#IBAction func addText(sender: AnyObject) {
annotationSelected = 3
}
#IBAction func drawCircle(sender: AnyObject) {
annotationSelected = 1
}
#IBAction func drawRectangle(sender: AnyObject) {
annotationSelected = 2
}
#IBAction func drawStamp(sender: AnyObject) {
annotationSelected = 4
}
This is all I have done. Here is a screenshot of my toolbar:
Here is what I got:
#IBOutlet var textToolButton: UIBarButtonItem!
#IBOutlet var circleToolButton: UIBarButtonItem!
#IBOutlet var rectangleToolButton: UIBarButtonItem!
#IBOutlet var stampToolButton: UIBarButtonItem!
then
textToolButton.target = self
textToolButton.style = .Done
textToolButton.action = #selector(ViewController.barButtonPressed)
let selectedBackgroundColor = UIImage(color: .redColor())
textToolButton.setBackgroundImage(selectedBackgroundColor, forState: UIControlState.Highlighted, style: .Done, barMetrics: UIBarMetrics.Default)
and then the method
func barButtonPressed(sender: UIBarButtonItem) {
print(sender)
annotationSelected = sender.tag
}
background is still not changing color
I find a same question. May be can help you.
custom-pressed-uibarbuttonitem-backgrounds
I find a easy method to do. You can dray a button to the toolBar,and you will see like this.
And you should change the button's type and Image.
storyboard screenshot
then you should link the button to your viewController.
#IBOutlet weak var textToolButton: UIButton!
and you can do.
let selectedBackgroundColor = UIImage(color: .redColor())
textToolButton.setBackgroundImage(selectedBackgroundColor, forState: .Highlighted)
May be I can help you.
The cleanest way you could do it, is create an overall function where you pass in the button that's been selected. Something like this:
var allButtons = [button1, button2, button3, button4]
func resetTabBar (buttonSelected:UIButton) {
for button in allButtons {
if button == buttonSelected {
button.backgroundColor = "Black"
}
else {
button.backgroundColor = "Blue"
}
}
}
And then in your functions you've created, just pass in the sender like so:
#IBAction func addText(sender: AnyObject) {
resetTabBar(sender)
}
Note: This is assuming you have outlets for all of your buttons. If you don't, add them.

Resources