Swift: Generate Identifier for Variable - swift

I have a large list of NSButtons (80+) that I assign to an array. I've used a numbering scheme to name them and I'd like to generate the identifiers for them instead of calling them directly by name one at a time.
#IBOutlet weak var button120: NSButton!
#IBOutlet weak var button121: NSButton!
var buttons [NSButton]()
Currently (in ViewDidLoad()) I'm doing the equivalent of:
buttons = [ button120, button121 ]
I'd prefer to do something like:
for index in 120...121 {
buttons.append("button\(index)".toIdentifier)
}
Can this be done in Swift?

This might be an easier solution, view is the parent view of the buttons
let buttons = view.subviews.filter { $0 is NSButton}

Related

attach several UILabels from storyboard to one IBOutlet

I've 15 Labels in my Storyboard they are just texts, also set from storyboard, What I want to do is to style them, but programitically, Therefore I need to create 15 IBOutlets in my ViewController, I wonder if there is any other way of doing that, without 15 IBOutlets,if it's possible to create 1 IBOutlet and attach all of them to that one? because creating 15 of them is kinda stressing...
You can do this with Outlet Collections instead of an IBOutlet for all the labels you want to group together:
One way to do it is to ctrl+drag from your storyboard to your editor and select outlet collection
This will create #IBOutlet weak var labelCollection: UILabel! in your code
This works fine but then you need to add an additional check for the type when looping:
#IBOutlet weak var labelCollection: UILabel!
func setCustomLayout()
{
for label in labelCollection2.subviews
{
if let label = label as? UILabel
{
// do your custom set up here
}
}
}
What I like to do is to create the specific outlet collection in code first if I way to track the same type like so:
#IBOutlet var labelCollection: [UILabel]!
The I drag from the editor to the storyboard
Then I can work with it as follows
#IBOutlet var labelCollection: [UILabel]!
func setCustomLayout()
{
for label in labelCollection
{
// do your customization here
}
}
Then you can loop through the UIViews inside the IBOutletCollection and do the needful

How to generate Labelname from a variable? (how to cast a string to UILabel)

I want to refer to a label based on the title of the button pressed.
I have a plenty of buttons, that I connected together in a single action. I want to be able to refer to only one label, that corresponds to the name of button pressed.
The Label names are: aLabel, bLabel, cLabel ...
The buttons pressed are titled "a", "b", "c"...
I ame creating the string with name of the label i want to refer to, but I can't use it as label name to change this particular label values.
I want to use this string to refer to the corresponding label, to change it title, color, and so on.
I tried, casting, looking for a function that changes strings into UILabels. I was also thinking about an array with pointers to the Labels, but I didn't succed even with establishing a pointer to a single Label...
//My code
#IBOutlet weak var a: UIButton!
#IBOutlet weak var b: UIButton!
#IBOutlet weak var c: UIButton!
#IBOutlet weak var aLabel: UILabel!
#IBOutlet weak var bLabel: UILabel!
#IBOutlet weak var cLabel: UILabel!
var currentLabel : String
#IBAction func FieldDisplay(_ sender: UIButton) {
currentLabel = sender.currentTitle! + "Label"
currentLabel.text = "OK"
}
//what I tried
(UILabel)currentLabel.text = "OK"
currentLabel = currentLabel.to.UIlabel
When interface objects are associated in multiple pairs like this — a series of button–label pairs, as you have it — there are two approaches commonly used. One is to assign each pair a tag. For example, in the storyboard, the first button would have tag 1, and the first label would have tag 101. Then the second button would have tag 2, and the second label would have tag 102. And so on.
So now in your IBAction function you look at the tag of the sender, add 100 to it, and call viewWithTag on your view to find the corresponding label.
The other possibility is to use outlet collections. Instead of three button outlets you have one array-of-button outlet; so too for the labels. Now in your IBAction function you get the firstIndex of the button in its array; that, if you've set this up correctly, is the index of the corresponding label in its array.
Remove all outlets and create 2 collections
#IBOutlet var allBts: [UIButton]!
#IBOutlet var allLbls: [UILabel]!
then hook all labels / btns to each , and set a tag for each group ( lbl1 && btn1 tag = 0 , lbl2 && btn2 tag = 1 and so on)
#IBAction func FieldDisplay(_ sender: UIButton) {
allLbls[sender.tag].text = sender.currentTitle! + "Label"
}
You can use value(forKey:) method
#IBAction func buttonTapped(_ sender: UIButton) {
if let currentLabel = value(forKey: sender.currentTitle! + "Label") as? UILabel {
currentLabel.text = "OK"
}
}
https://developer.apple.com/documentation/objectivec/nsobject/1412591-value

How can I create a function for multiple labels in a stack?

I have 3 labels and I want to generate random numbers for each of them. I use GKRandomSource class in function, thats ok. The problem is, if I want to have much more labels (ie. 30) and all with same action, I need to reference all labels one by one to IBAction, I need to state all labels one by one in func code… I’ve been searching for a shorter way, maybe put them all in 3 stacks (10 labels for each stacks) and trigger, but I got nothing. I tried outlet collections (as we use in UIButtons) but it doesn’t let me to change label text.
How can I use a function for multiple labels with no-repeat?
Example;
let allNumbers = [Int](1...99)
var shuffledNum = [Int]()
#IBOutlet weak var labelOne: UILabel!
#IBOutlet weak var labelTwo: UILabel!
#IBOutlet weak var labelThree: UILabel!
func generateNumbers() {
shuffledNum = GKRandomSource.sharedRandom().arrayByShufflingObjects(in: allNumbers) as! [Int]
let threeNumbers = shuffledNum.prefix(3).sorted()
labelOne.text = String(threeNumbers[0])
labelTwo.text = String(threeNumbers[1])
labelThree.text = String(threeNumbers[2])
}
you can make the array of UILabel's and put all the outlets in the same array then you can use for loop to do operations on each of them.
for example:
#IBOutlet var formLabels: [UILabel]!
and can do as:
formLabels.forEach { label in
label.text = ""//put your random number function here
}
see its working after adding both outlets I have also shown the connection in the storyboard the connection exists

How to use random variable to choose correct button in swift

The title might not be the best explanation of what I want but I couldn't think of a better way to describe it.
#IBOutlet var button0: UIButton!
#IBOutlet var button1: UIButton!
#IBOutlet var button2: UIButton!
var num = (arc4random()%3);
basically I want to use the variable 'num' to choose which button and make it hidden based off the random number. Is there a way to use the variable in a a simple line like "button(num).hidden = true" or something like that?
[button0, button1, button2][num]
Basically, all you want to do is create an array of UIButtons!, and then set array[num].enable = false.
you can basically store your buttons into a array of UIButton, and then use this array randomly.
Code
self.buttons.append(button0)
self.buttons.append(button1)
self.buttons.append(button2)
self.buttons[Int(num)].hidden = true
var num = Int(arc4random_uniform(3))
let buttons:[UIButton] = [button0,button1,button2]
buttons[num].hidden = !buttons[num].hidden
Create an array that stores all your UIButtons
var buttonsArray: [UIButton]!
Access one of the UIButtons from the Array randomly and hide the accessed UIButton
var randomNum: Int = Int(arc4random()%3)
var button = buttonsArray[randomNum]
button.hidden = true

How to add a custom uiview to a view controller programmatically SWIFT

I am trying to add a custom view programmatically to my view controller. I used this snippet of code with no success of it appearing in front of my main view controller.
var DynamicView = CustomFilter()
DynamicView.setTranslatesAutoresizingMaskIntoConstraints(false)
self.view.addSubview(DynamicView)
CustomFilter Class:
import UIKit
class CustomFilter:
UIView {
#IBOutlet weak var party: UIButton!
#IBOutlet weak var outdoors: UIButton!
#IBOutlet weak var sports: UIButton!
#IBOutlet weak var diner: UIButton!
#IBOutlet weak var music: UIButton!
#IBOutlet weak var gaming: UIButton!
}
The custom filter is connected to a xib file.
Xib File:
Is there a possibility that the custom view maybe out of placed? I'm not sure what I'm doing wrong.
In order to use a view we designed in a xib, we most load from the xib.
if
let bundle = NSBundle(forClass: CustomFilter.self),
let nib = bundle.loadNibNamed("<#Xib File Name#>", owner: self, options: nil),
let dynamicView = nib.first as? CustomFilter {
self.view.addSubview(dynamicView)
}
An alternative approach would be to write your CustomFilter's init to load the view from the xib itself.
More clearly, the problem you're having is that none of your CustomFilter's initializers are going to care about the xib file you made unless you write them and tell them to care about it. Your current code is returning a 0x0 view with probably a white or clear background. If you modified your current code to set the CustomFilter's frame to something other than 0x0 size and set the background color to something like UIColor.greenColor(), you'd see it clear as day.
Also, you could use Xcode's visual debugger to find it.
It's probably zero height and zero width, and may be off-screen also.
You need to give it height and width constraints and x and y position constraints.
You should probably also use CustomFilter(frame: someFrameRect), since as I recall initWithFrame is the designated initializer for UIView.
As an aside, variable names should start with a lower-case letter, so DynamicView should be dynamicView