create a UIButton for each object in array - swift

Hello guys I want to create a UIButton programmatically from every object in an array. something like
for answer in answers {
//create button
}
But how do I assign all these buttons a randomized and unique variable?
like var randomvar = UIButton() ?

I had this problem when I was new to OOP x).
Basically a variable when handling an object is just a pointer to the address in memory.
An array with objects will actually be an array with pointers to all unique objects, in your case these objects are UIButton's.
So in your for-loop you have to add those buttons inside another array.
var buttons = [UIButton]()
for answer in answers {
let btn = UIButton()
...
buttons.append(btn)
}
Then you can access each unique button by accessing them trough buttons.
buttons[2].setTitle("test 2", forControlEvent: .Normal)

Loop over your array and create the button for each item. Either add it to your view directly or save it into an array for later access
var buttons = [UIButton]()
for answers in answer {
let button = UIButton(...)
button.addTarget(self, action: "buttonAction:", forControlEvents: . TouchUpInside)
// add to a view
button.frame = ...
view.addSubview(button)
// or save for later use
buttons.append(button)
}

The better approach is to create an array property:
var array: [UIButton]?
and inside the loop create a button and add it to this array.
If you need to access any button you can access it by index.

Related

Swift dropDown library

I am using the dropdown library. When you press a button, you want to develop it in a format where text changes on the button when you click an element.I can print but I don't know how to change the text of the button. And I want to change the sort order of the table view when I click that element. How should I do it?
func dropDown() {
sequenceDropDown.dataSource = ["Latest order
", "Priority"]
sequenceDropDown.show()
sequenceDropDown.anchorView = sequence
sequenceDropDown.bottomOffset = CGPoint(x: 0, y:(sequenceDropDown.anchorView?.plainView.bounds.height)!)
sequenceDropDown.selectedTextColor = .white
sequenceDropDown.selectionBackgroundColor = .mainColor
}
This is dropDown function.
output.loadData.bind(to: tableView.rx.items(cellIdentifier: "mainCell", cellType: MainCell.self)) { row, element, cell in
cell.nameLbl.text = element.nickname
cell.titleTxtField.text = element.title
cell.contentTxtView.text = element.description
cell.postImage.image = UIImage(named: element.media)
cell.timeLbl.text = element.date
cell.sirenBtn.rx.tap.subscribe(onNext: { _ in
self.selectIndexPath.accept(row)
}).disposed(by: self.disposeBag)
}.disposed(by: disposeBag)
This is binding tableview code.
setting button's title is easy myButton.setTitle("Play", for: .normal)
if you want to change sort of table view, you probably should map loadData observable to needed sort method, maybe it's even better to store ouput from loadData to some array and wrap it to observable or subject, bind it to table view and if you need to see sorted tableview just sort the array
(maybe I didn't get you case point completely)

find descendant buttons in nested container

I have placed buttons in multiple nested StackViews
I then placed the views within a CollectionView (yes I recognize this isn't necessarily the best or optimal way to do this).
I'm trying to figure out how I can programmatically find all my buttons.
If I do this, all I get is my StackView instead of getting the buttons (which are now 3rd level descendants). I'd love to not have to right a nested loop and instead find a function that helps me find all descendants of type UIButton.
for subview in buttonContainer.subviews {
let button = subview as? UIButton
if button != nil {
button!.setTitle("TEST", for: UIControl.State.normal)
}
}
The reason I'm doing this is just as an exercise to learn different methods, which is why I am ok nesting multiple stack views and then placing them within a CollectionView
You need to create a recursive method like:
func buttonsIn(_ view: UIView) {
if let button = view as? UIButton {
button.setTitle("TEST", for: .normal)
} else {
view.subviews.forEach({ buttonsIn($0) })
}
}
Usage:
buttonsIn(view)
Modify the recursive method as per your requirement.
I didn't test it but using recursion you should be able to accomplish this. Something like this may work for you:
func findButtonsIn(_ view: UIView) -> [UIButton] {
var buttons: [UIButton] = []
view.subviews.forEach({
if let button = $0 as? UIButton {
buttons.append(button)
} else {
buttons.append(contentsOf: self.findButtonsIn($0))
}
})
return buttons
}
Usage
findButtonsIn(yourView)
The function will return all found UIButtons as an array.
You could use
self.findButtonsIn(UIView()).enumerated().forEach({
$0.element.setTitle("\($0.offset)", for: .normal)
})
for example to set the buttons title according to the order they were found in.

How to add to an array when button is pressed?

I've got custom buttons on a custom tableview cell, when button is pressed the image changes to checked/unchecked (see code below).
Issues is: How do I add the cell row data thats checked to an array that will be its own table (eg. a table with only checked data).
#IBAction func tickAction(sender: UIButton) {
println("SSSS")
if (sender.selected) {
sender.setImage(UIImage(named:"Unchecked.png"), forState: .Normal)
sender.selected = false
}
else {
sender.setImage(UIImage(named:"Checked.png"), forState: .Normal)
sender.selected = true
}
}
A solution would be to extend UITableViewCell into your own class that holds the other data or holds a reference to a model that holds the data.
Ideally, the view controller should hold the models and should get notified by a view that the action took place to act accordingly. The view controller should then add the data to the other array.

How to loop through buttons

I have 16 buttons named like btn1, btn2 etc.. how can i loop through this and set an value to each button?
I have this code:
//set values on the button
for i in 1..<17{
var mybutton = "btn" + String(i);
println(mybutton)
mybutton.setTitle(String(number), forState: UIControlState.Normal)
}
}
but that doesn't work because the software sees it as an string...
How can i solve this issue?
You can create array of buttons:
let array = [btn1, btn2, btn3 ...]
for i in array.count
{
//do something
array[i].setTitle(String(number), forState: UIControlState.Normal)
}
But if you have a lot of buttons in Interface Builder, the better way to create them programmatically.
In addition to the answer of ChikabuZ:
If you separately added the buttons in storyboard, I suggest you to create an outlet collection instead: #IBOutlet var buttons: [UIButton]!.
CTRL drag all those buttons in this outlet and you can access the array like ChikabuZ has suggested.
I personally prefer to use a map instead:
buttons.map { $0.setTitle(String(number), forState: .Normal) }
If you added these in the interface builder and have a reference to the superview, you can assign each of them a tag from 1 to 16 access them using the method "viewWithTag":
//set values on the button
for i in 1..<17{
var sView = [REFERENCE TO YOUR SUPERVIEW HERE]
var mybutton = sView.viewWithTag(i) as! UIButton?
println(mybutton)
mybutton.setTitle(String(number), forState: UIControlState.Normal)
}
}

Referencing a UIButton by tag value

I am aware that a pushed button can be updated by reference to sender.
However I want to access a button from the program body by reference to its tag and then update its label,if that is possible.
Suggestions on how to do this (in Swift) would be appreciated.
To get a button inside a view using its tag, you can use the UIView.viewWithTag function.
if let button = self.view.viewWithTag(tag) as? UIButton
{
button.setTitle("newTitle", forState: UIControlState.Normal)
}
You have to use viewWithTag
ex:
var button = self.view.viewWithTag(tagNumber) as UIButton
button.setTitle("Button Title", forState: UIControlState.Normal)
Set the tag for all buttons. Then have a property
var buttons = [UIButton]
and in your awakeFromNib init it
buttons.append[myButtonWithTag0]
buttons.append[myButtonWithTag1]
// etc
Now you can access your buttons via
let button = buttons[index]
Swift3 : Possible with viewWithTag(button_tag) as:
let tmpButton = self.view.viewWithTag(tag) as? UIButton
tmpButton?.setTitleColor(.red, for: .normal)
tmpButton?.setTitle("Button Title", for: .normal)