How to change button programmatically without outlet connection in swift - ios

I have a list of buttons inside an array. I want to replace the buttons position order using that array. I can do this in java, but cant do the same in swift. Here is my code:
#IBOutlet weak var menuView: UIView!
struct ButtonsIndex {
var button: UIButton
var index: Int
}
var footer: [ButtonsIndex] = []
//Set Buttons order etc
...
func setFooter(){
let count = 0
for buttons in menuView.subviews {
if var button = buttons as? UIButton {
button = footer[count].button
count += 1
}
}
}
Is it impossible to change the buttons position without connecting the outlets to my code? Thanks in advance.

Related

Setting isHidden to false on x amount of elements

I am trying to unhide n number of elements depending on the users input into a text field.
So the user enters a number between 1 - 5 in the text field then clicks submit which calls createSplit. As you can see, it unhides a view and then I want it to loop x (x being the number the user inputs) amount of times to unhide day(i)View textfield
#IBAction func createSplit(_ sender: Any)
{
noOfExerciseView.isHidden = false
let noOfDays: Int = Int(numberOfDays.text!)!
for i in 1...noOfDays
{
day\(i)View.isHidden = false
}
}
I have a working solution but it's not the most efficient so I hope someone can help doing this an efficient way.
#IBAction func createSplit(_ sender: Any)
{
noOfExerciseView.isHidden = false
let noOfDays: Int = Int(numberOfDays.text!)!
for i in 1...noOfDays
{
if (i==1)
{
day1View.isHidden = false
} else if (i==2)
{
day2View.isHidden = false
} else if (i==3)
{
day3View.isHidden = false
} else if (i==4)
{
day4View.isHidden = false
} else if (i==5)
{
day5View.isHidden = false
}
}
}
String interpolation cannot be used to set the name of a variable:
day\(i)View.isHidden // does not work
Your best bet is to use an outlet collection to define all your day views.
Instead of this:
#IBOutlet var day1View: UITextField!
#IBOutlet var day2View: UITextField!
#IBOutlet var day3View: UITextField!
//...
Do this:
#IBOutlet var dayViews: [UITextField]!
Then you can write your loop like this:
for i in 0...noOfDays-1
{
dayViews[i].isHidden = false
}
Note that to do this, you'll need to delete the existing outlets and reconnect them.
If you're using a storyboard, then when you Control-drag from your first text field to your class file, select Outlet Collection for the Connection type and name it dayViews. To add the remaining text fields to the collection, just Control-drag from each one to the dayViews var in your class file.

Sum of three textfield value without clicking a button (Swift - Xcode)

I'm currently having problems for my label to read the addition of 3 textfield values automatically, without a button function action. As such i only want my textfield to be an Int input only. There's a screenshot attached below for better reference. Appreciate those who can help me with this. Thanks!
ViewController
import UIKit
class TryingoutController: UIViewController {
#IBOutlet var impact: UITextField!
#IBOutlet var rigour: UITextField!
#IBOutlet var response: UITextField!
#IBOutlet var total: UILabel!
One way is to add self as the target to the text fields, for the control event .editingChanged
impact.addTarget(self, action: #selector(textChanged), for: .editingChanged)
// do the same for other textfields
Then declare a textChanged method. This should handle what happens when the texts in the text fields change. One implementation would be to add up all the values in the text fields (if any, and is valid) and display it in the label.
func textChanged() {
let impactValue = Int(impact.text!)
let rigourValue = Int(rigour.text!)
let responseValue = Int(response.text!)
total.text = String(describing:
(impactValue ?? 0) + (rigourValue ?? 0) + (responseValue ?? 0)
)
}
Optionally, you can conform to UITextFieldDelegate:
class TryingoutController: UIViewController, UITextFieldDelegate {
}
and implement shouldChange according to this answer by Thuggish Nuggets. Then, set the delegates of the text fields to self:
impact.delegate = self
// do the same for other text fields.

How can I make a UIImage View clickable to segue to another view controller

I'm new in programming and I'm stuck with this little problem. I created a table view with several items, that passes data to a label and an image view through a segue. It all works fine, but now I want to make the image clickable, in order to segue to another view controller to show this image expanded. How can I do that?
class ViewController: UIViewController {
#IBOutlet var titleLabel: UILabel!
#IBOutlet var descLabel: UILabel!
#IBOutlet var imageView: UIImageView!
var titleName: String?
var descName: String?
var imageName: String?
func configureView() {
if let poster = self.imageName {
if let imagePoster = self.imageView {
imagePoster.image = UIImage (named: poster)
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
titleLabel.text = titleName
descLabel.text = descName
self.configureView()
}
The easiest thing to do is to use a UIButton instead of an image view. Set it's type to custom and install the image into the button in IB (Interface Builder).
That way you can trigger an IBAction just like any other button. It also highlights on a touch like you'd expect, triggers on touch up rather than touch down, etc.
If you don't want to use a button-with-image, you have to set userInteractionEnabled = YES on the image view and install a tap gesture recognizer on it. See the docs on UITapGestureRecognizer for more information.

Object in tableViewCell are shown only when cell selected

I have custom UITableViewCell, which has button and progress view. It has 5 progress view objects.
In viewController.swift I have a struct where 6 variables (one of type button and five of type progress view) are.
When I'm clicking this button, I'm setting struct variables to these five progress view objects. Also NSUrlSession function starts which downloading file. Downloading progress must be shown in these progress views. And it working properly except moment that to see these progress view I must focus, select this cell. How can I fix it so by clicking this button all progress view will be shown in cell without its selecting?
Some code:
struct vis {
static var b: UIButton!
static var p1: UIProgressView!
static var p2: UIProgressView!
static var p3: UIProgressView!
static var p4: UIProgressView!
static var p5: UIProgressView!
}
vis.b = (sender as? UIButton)!
vis.p1 = (cell?.viewWithTag(5) as? UIProgressView)!
vis.p2 = (cell?.viewWithTag(6) as? UIProgressView)!
vis.p3 = (cell?.viewWithTag(7) as? UIProgressView)!
vis.p4 = (cell?.viewWithTag(8) as? UIProgressView)!
vis.p5 = (cell?.viewWithTag(9) as? UIProgressView)!
You can disable cell selection by tableView.allowsSelection = NO; and then you can use progressTintColor and trackTintColor or progressImage and trackImage to manage the colors for your progress controls.

Setting Title of UIbuttons in loop in swift

I have made a collection of UIButtons like this
#IBOutlet var btnChannle1:UIButton!
#IBOutlet var btnChannle2:UIButton!
#IBOutlet var btnChannle3:UIButton!
#IBOutlet var btnChannle4:UIButton!
#IBOutlet var btnChannle5:UIButton!
#IBOutlet var btnChannle6:UIButton!
#IBOutlet var btnChannle7:UIButton!
#IBOutlet var btnChannle8:UIButton!
#IBOutlet var channlesCollection:Array<UIView>!
override func viewDidLoad() {
super.viewDidLoad()
channlesCollection.append(btnChannle1)
channlesCollection.append(btnChannle2)
channlesCollection.append(btnChannle3)
channlesCollection.append(btnChannle4)
channlesCollection.append(btnChannle5)
channlesCollection.append(btnChannle6)
channlesCollection.append(btnChannle7)
channlesCollection.append(btnChannle8)
}
now I want to traverse the collection above and want some thing like this
for item in channlesCollection{
// Set Button Text Line to 2
// Set Button Text Like this in two line
/*
01
CNN
02
BBC
03
PTV ...
*/
}
but when Im trying like this.
for item in channlesCollection{
item.setTitle("Test", forState: UIControlState.Normal)
}
error raised UIView does not have member named setTitle.
You need to type-cast item as UIButton. Here is the code:
for item in channlesCollection{
var button:UIButton = item as UIButton
button.setTitle("Test", forState: UIControlState.Normal)
}
You are having array of UIView and they indeed don't having a setTitle method. Either make your collection of type UIButton. Or cast your current collection items to buttons:
for item in channlesCollection {
if var button = item as? UIButton {
button.setTitle("Test", forState: UIControlState.Normal)
}
}
UIView does not have a member function setTitle, but UIButton has, which is probably what you want.
You have declared your channlesCollection as array of UIView, why not as array of UIButton?
var channlesCollection: [UIButton]!

Resources