I'm creating a textfields in viewDidLoad and i have a add new textfield button. I'm adding new textfields, but not deleting. I just don't do it because i am new. Here is my addNewTextField button func :
#IBAction func addNewTextField(sender: AnyObject) {
var myTextField: UITextField = UITextField(frame: CGRect(x: 0, y:0, width: 200.00,height: 240.00));
myTextField.placeholder = "write something"
myTextField.center = CGPointMake(160, CGFloat(height2))
height2 = height2 + 50;
self.arrayOfTextFields.append(myTextField)
self.view.addSubview(myTextField)
}
How can i delete this textfields and arrays with another button ?
You can create a new func or IBAction and create a loop to go through all of the elements in self.arrayOfTextfields. You can then grab each textfield from the array and remove it from the superview. When the loop is finished, you can clear the array.
Something like this:
for textField in arrayOfTextFields {
textField.removeFromSuperview()
}
arrayOfTextFields = []
Related
I have a tableview in my view controller with a custom cell. in the cell I have a function that is suppose to do something. I have a print statement that is getting executed.
#objc func cellButtonTapped() {
cellText.backgroundColor = .red
print("cell button tapped")
}
when I tap the button I do see in my console the print statement, but its not changing the cell background color like I want it to.
this is the cellText in the tableViewCell
let cellText : UITextField = {
let cellText = UITextField()
cellText.isUserInteractionEnabled = false
return cellText
}()
this is how its layout is in the cell. I don't think its layout is important
override func layoutSubviews() {
super.layoutSubviews()
contentView.addSubview(cellText)
contentView.addSubview(cellButton)
cellText.frame = CGRect(x: 0,
y: 0,
width: contentView.width - 30,
height: contentView.height)
cellButton.frame = CGRect(x: cellText.right, y: 0, width: 30, height: contentView.height)
}
what I had to do is create a variable in the viewController with the value that the cell needs. in my case I wanted a bool value to be carried over.
var isBool : Bool = false
then I let the function for the button to change the variable value:
#objc func sendButtonTapped() {
isBool = !isBool
tableView.reloadData()
print("send button tapped")
}
the function here changes the value of my bool every time I click the button.
I transferred the value to the cell with the cellForRowAt in the tableview.
I created a UIlabel named etiket. then I created an action button and I made changes like color change on it. it's a sample:
#IBAction func changeColor(_ sender: Any) {
etiket.textColor = UIColor.red
then I created again an action button and now when I pressed the button I want to reset UIlabel to default settings.
I tried this method
#IBAction func sifirla(_ sender: Any) {
etiket.text = "nil"
when I tried this method UIlabel completely disappeared.
How can I reset UIlabel attributes to default settings?
I did some research, but I could not find exactly what I wanted.
You need to create a label dynamically and assign a tag value to it.
func createLabel() -> UILabel {
let lbl = UILabel(frame: CGRect(x: 10, y: 10, width: 100, height: 55))
lbl.tag = 101
//set other properties of label
return lbl
}
In changeColor method you need to get label by tag value and set its color.
#IBAction func changeColor(_ sender: Any) {
if let lbl = self.view.viewWithTag(101) as? UILabel {
lbl.textColor = UIColor.red
}
}
In sifirla method you need to get label by tag value and remove it from its super view and create a new label and add it in your current view, so by adding a new UILabel instance you will get default settings of label.
#IBAction func sifirla(_ sender: Any) {
if let lbl = self.view.viewWithTag(101) as? UILabel {
lbl.removeFromSuperview()
let newLbl = self.createLabel()
self.view.addSubview(newLbl)
}
}
Note: If you are using autolayout then you need to set constraint to label instead of frame.
I am working on an application in Swift. At the beginning I provide number of inputs that I would like to add. In next view I create as many UITextFields as I defined in first view.I have a problem with storing of all this values from TextFields after pressing the button. It seems to me that the most effective solution is to create an array of UITextFields and add every value of TextField into array and then in action for button adding values which are in all TextFields into array. Unfortunately, it doesn't work. Any suggestions? Thanks in advance.
override func viewDidLoad() {
super.viewDidLoad()
var counter = 0
for i in 1...mainInstance.numberOfInputs
{
super.viewDidLoad()
array.insert(UITextField(frame: CGRect(x: 0, y: 50, width: 60, height: 20)), at: i)
array[i].center = CGPoint(x: 200,y: 50 + counter)
array[i].textAlignment = NSTextAlignment.center
array[i].layer.borderWidth = 1
array[i].layer.borderColor = UIColor.black.cgColor
self.outletScrollView.addSubview(array[i])
counter += 50
}
super.viewDidLoad()
let button = UIButton(type: .system) // let preferred over var here
button.frame = CGRect(x: 200, y: 50 + counter, width: 100, height: 20)
button.setTitle("Recalculate", for: UIControlState.normal)
button.addTarget(self, action: "actionRecalculate:", for: UIControlEvents.touchUpInside)
self.outletScrollView.addSubview(button)
outletScrollView.contentInset = UIEdgeInsetsMake(0, 0, CGFloat(counter+100), 0)
}
You could create easily with:
let textFields = [UITextField]()
You should consider using an UIScrollView, (like in your example) or (better idea in my opinon) a UITableView to add your UITextfields. So you have multiple Rows, and every row has one UITextField. The number of rows / Textfield can u easily customize (and get it from your FirstViewController for example).
Just create a custom UITableViewCell - add an UITextField and connect the IBOutlet. To get the values from every UITextField you could iterate through all cells, and read out the values. Just ask, if you need more help about doing that.
Creating array of UITextfield could be done this way
// Create an empty array of type UITextField
var listOfTextFields : [UITextField] = []
// In viewDidLoad, create a textfield and add it to the array
override func viewDidLoad() {
super.viewDidLoad()
for i in 0...mainInstance.numberOfInputs-1 {
let textField = UITextField((frame: CGRect(x: X, y: Y*i, width: yourWidth, height: yourHeight)))
textField.delegate = self
listOfTextFields.append(textField)
}
}
In this UITextField setup, I didn't account for any formatting to shorten the answer.
Though this might not be for the exact use case, it could help others with similar use cases (particularly programmatically created textfields or custom uicell).
txtfield.tag = indexPath.row // or other int
Then you implement textfield didEndEditing after array has been initialized and delegating
#IBAction func endedEditing(_ sender: UITextField) {
arr[sender.tag] = sender.text
}
EXPLANATION:
1) I initiate the button above the class :
var myButton = UIButton()
2) I then create x amount of buttons depending on how many items are in an array
for letter in arrayOfLetters {
myButton = UIButton(frame: CGRect(x: buttonX, y: 500, width: someFloat, height: someFloat))
buttonX = buttonX + thirdFloat //spacing
myButton.layer.cornerRadius = 5
myButton.backgroundColor = UIColor.darkGrayColor()
myButton.setTitle("\(letter)", forState: UIControlState.Normal)
myButton.titleLabel?.text = "\(letter)"
myButton.addTarget(self, action: "myButtonPressed:", forControlEvents: UIControlEvents.TouchUpInside)
self.view.addSubview(myButton)
}
3) Later on once the user has pressed the correct buttons, I call a function to refresh and I want to remove all buttons. This is so I can generate new buttons based on new array
myButton.removeFromSuperview()
ISSUE:
However this does nothing, I tried giving the buttons a tag and deleting buttons by tag == tagId but nothing happened.
I can delete all views but it deletes everything else,
I tried this but again nothing happends
var buttons = [myButton]
for button in buttons as! [UIButton] {
button.removeFromSuperview()
}
I want to delete all buttons I added and i'm either not deleting them or deleting everything in the view
EASY FIX:
1) Inside Class, out of any func:
var buttonsArray = [UIButton]()
2) Declare myButton here and add the append line:
for letter in arrayOfLetters {
var myButton = UIButton(frame: CGRect(x: buttonX, y: 500, width: someFloat, height: someFloat))
...
self.buttonsArray.append(myButton)
}
3) To remove buttons:
for btn in buttonsArray {
btn.removeFromSuperview()
}
EXPLANATION:
Always store in an array the elements you create with a loop if you want to easily remove all of them at once.
i hope it will help for you give tag for your button while you are adding delete that button
for button in self.view.subviews {
if button.tag == 100 {
button.removeFromSuperview()
}
}
you are re-assigning the myButton variable as you loop.
Remove this line:
var myButton = UIButton()
add a property at the top to hold the buttons:
var buttons:[UIButton]()
then later in your code:
for letter in arrayOfLetters {
var myButton = UIButton(frame: CGRect(x: buttonX, y: 500, width: someFloat, height: someFloat))
buttonX = buttonX + thirdFloat //spacing
myButton.layer.cornerRadius = 5
myButton.backgroundColor = UIColor.darkGrayColor()
myButton.setTitle("\(letter)", forState: UIControlState.Normal)
myButton.titleLabel?.text = "\(letter)"
myButton.addTarget(self, action: "myButtonPressed:", forControlEvents: UIControlEvents.TouchUpInside)
self.view.addSubview(myButton)
self.buttons.append(myButton)
}
Then you should be able to remove like so:
for button in self.buttons {
button.removeFromSuperview()
}
This should resolve your issue, But it's important to understand what the problem was, so you define a new button as a property with this line: var myButton = UIButton(). This holds ONE button. as you are looping through creating buttons you are overriding the button with the next one.
So if anything, Calling myButton.removeFromSuperView() will remove the last one you created. Doing it the way I suggested means you create a button and add it to an array of buttons, so later you can iterate over the array referencing each button in turn and remove it.
I'm adding a few UISteppers and UITextFields programmatically, based on user's preferences. However, I can't seem to get the UIStepper touch to click - it looks like it's not registering the touch on the -/+ buttons. I tried setting User Interaction of the userTriggers UIView to disabled, but that didn't work.
1) What else can I try?
2) I also need to be able to increment the corresponding UITextField, and then write that into my UserData.plist file, and I'm not sure how to access each field. Should I add them to an array of some sort?
import UIKit
class TriggersViewController: UIViewController{
#IBOutlet var userTriggers:UIView!
#IBOutlet var saveButton:UIButton!
var triggersList:Array<String>!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
loadTriggers()
var prevInput = 250;
for index in 0..<triggersList.count{
//label for trigger
var label = UILabel(frame: CGRectMake(0, 0, 200, 21))
label.center = CGPointMake(120, CGFloat(prevInput))
label.textAlignment = NSTextAlignment.Left
label.text = triggersList[index]
userTriggers.addSubview(label)
//input box for trigger
var input = UITextField(frame: CGRectMake(0, 0, 50, 21))
input.center = CGPointMake(250, CGFloat(prevInput))
input.text = "0";
//add input to triggersView
userTriggers.addSubview(input);
//UIStepper
var stepper = UIStepper(frame: CGRectMake(0, 0, 50, 21))
stepper.center = CGPointMake(300, CGFloat(prevInput))
stepper.addTarget(self, action: "stepperValueChanged:", forControlEvents: .ValueChanged)
stepper.enabled = true
//add stepper to triggersView
userTriggers.addSubview(stepper);
prevInput += 50 //increment for height
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func stepperValueChanged(sender:UIStepper!){
println("It Works, Value is -->\(Int(sender.value).description)")
}
func loadTriggers(){
var myDict: NSDictionary?
if let path = NSBundle.mainBundle().pathForResource("UserConfigs", ofType: "plist") {
myDict = NSDictionary(contentsOfFile: path)
}
if let dict = myDict {
triggersList = dict["Triggers"] as Array<String>
}
}
}
You actually need to set user interaction on the superview to enabled. See here for more info: UIView -- "user interaction enabled" false on parent but true on child?
Also, re: second question an easy (but not so ideal) way to access each field is using tags. Clean-ish way to do that is define tags using an enum. Then access the fields using viewWithTag.
However, there are better ways than tags (e.g. they're not very error-proof because any view can be given any tag). If it's only a few text fields / steppers though you could just as easily add properties to your view controller for each one. The best solution would be to group the steppers and fields together in a UIView subclass (assuming they're next to each other) and store references to those groupings in your view controller (possibly in an array).