I am trying to show multiple textFields by running a loop, that whether the number of textfields noTextField is greater than zero (which is an input value), it should display the multiple textFields on ViewController.
Here is what I have one textfield and prints multiple hello but could not display multiple textfields.
What I have
enter image description here
What I want
enter image description here
if self.noTextFields! > 0 {
for _ in 0..<self.noTextFields! {
// self.createForm()
print ("hello")
let sampleTextField = UITextField(frame: CGRect(x: 20, y: 100, width: 300, height: 40))
sampleTextField.placeholder = "Enter text here"
sampleTextField.font = UIFont.systemFont(ofSize: 15)
sampleTextField.borderStyle = UITextBorderStyle.roundedRect
sampleTextField.autocorrectionType = UITextAutocorrectionType.no
sampleTextField.keyboardType = UIKeyboardType.default
sampleTextField.returnKeyType = UIReturnKeyType.done
sampleTextField.clearButtonMode = UITextFieldViewMode.whileEditing;
sampleTextField.contentVerticalAlignment = UIControlContentVerticalAlignment.center
sampleTextField.delegate = self as? UITextFieldDelegate
self.view.addSubview(sampleTextField)
}
}
Mistakes and Corrections:
Check the SubView items contents for the self.view by self.view.items values printing in logs.
You have not assigned the X / Y position for the +1 counter text fields you are allocating to any incremental position so even if the new object will get created it will be overlapped on the same previous item.
I would always recommend to put the textfield object in array at same time when you do addSubview call, immediately after this self.view.addSubview(sampleTextField) call. This will help me to save the reference for each text field item when required to modify / access / deallocate.
You also set the tag for each textfield object so its better to get the object with that tag from the subviews with [self.view viewWithTag:tagNo] call if you dont want an array to be used.
Your snippet will look like
var xValue = 0,yValue =0
var tagNo = 0
var textObjects = allocate new array.
if self.noTextFields! > 0 {
for _ in 0..<self.noTextFields! {
// self.createForm()
print ("hello")
let sampleTextField = UITextField(frame: CGRect(x: xValue, y: yValue, width: 300, height: 40)) //Note that I have set xValue and yValue
sampleTextField.placeholder = "Enter text here"
sampleTextField.font = UIFont.systemFont(ofSize: 15)
sampleTextField.borderStyle = UITextBorderStyle.roundedRect
sampleTextField.autocorrectionType = UITextAutocorrectionType.no
sampleTextField.keyboardType = UIKeyboardType.default
sampleTextField.returnKeyType = UIReturnKeyType.done
sampleTextField.clearButtonMode = UITextFieldViewMode.whileEditing;
sampleTextField.contentVerticalAlignment = UIControlContentVerticalAlignment.center
sampleTextField.delegate = self as? UITextFieldDelegate
sampleTextField.tag = tagNo //Note this line for tagNo
self.view.addSubview(sampleTextField)
textObjects.addObject:sampleTextField //Note this line for adding textfield to array for reference to get total items added
yValue = yValue + sampleTextField.frame.size.height + 20; //Added yValue to place another text view at bottom of initial one and 20px buffer for gap.
}
}
print "Total Textobjects in array:textObjects.count
If required to get object from view its self.view.viewwithTag(tagNo) will return exact text field.
You just add dynamic value of y(add x if required).
var counter = 30
var yValue = 0
in for loop you just need to add below code
let sampleTextField = UITextField(frame: CGRect(x: 20, y: yValue, width: 300, height: 40))
yValue = Counter
//(space each textfield if 30 because height of textfield is 40)
counter = counter + 70
Related
After creation of a list of Label created with this func:
func addElongationlabel() {
let elongationLabel = UITextView(frame: CGRect(x: 100, y: ordinata, width: 90, height: 35))
elongationLabel.textAlignment = NSTextAlignment.center
elongationLabel.tag = ordinata
elongationLabel.textColor = UIColor.blue
elongationLabel.backgroundColor = UIColor.red
view.addSubview(elongationLabel)
}
I'm obtaining a list of label using this cycle of For:
for i in 1...Int(numberOfDiesText.text!)!{
ordinata = 220 + 50*i
addElongationlabel()
}//end of for
Now I want to assign to my Labels a value calculated. I'm trying with this code but it is not working:
for i in 1...Int(numberOfDiesText.text!)!{
ordinata = 220 + 50*i
if let eloLabel = (self.view.viewWithTag(ordinata)as? UILabel){
// here I think I have to insert the correct command
self.view.viewWithTag(ordinata) = eloLabel // this is not working...of course
}
}//end of for
Thank you to help me!
I am trying to add custom view (Label) as title view of navigation item.
but it is not appearing in centre
func setupNavigationMultilineTitle(title:String) {
let autoscrollLabel = EFAutoScrollLabel()
autoscrollLabel.text = title
autoscrollLabel.textAlignment = .center
autoscrollLabel.backgroundColor = .red
autoscrollLabel.font = AppTheme.Fonts.font(type: .Medium, size: 15)
autoscrollLabel.textColor = AppTheme.Colors.ColorsOfApp.header_color.color
autoscrollLabel.frame = CGRect(x: 0, y: 0, width:((self.navigationController?.navigationBar.frame.size.width ?? 0) - (self.navigationItem.leftBarButtonItem?.customView?.frame.width ?? 0) * 2) , height: 40)
self.navigationItem.titleView = autoscrollLabel
}
I have tried to use deduct width of custom view to show it in center but unfortunately it is not working.
I have also tried to get self.navigationItem.leftBarButtonItem.width but it returns 0. I confirmed that there is leftBarbutton item with po self.navigationItem.leftBarButtonItem
EDIT
This solves issue
autoscrollLabel.frame = CGRect(x: self.view.center.x - 125, y: 0, width: 250 , height: 40)
But I need dynamic solution
Any help would be appreciated
I debugged your scenario, hope it helps you and other developers,
When we assign tittleView width by calculating the space left after subtracting space of items, margins, padding etc then iOS calculate titleView X from the right side i.e. titleview.x = rightItem.x - width and we are expecting it like titleview.x = navbar.width/2 - width/2.
Please look below sample test cases.
Calculate width
let maxItemOnEitherSide = max(arrLeftItems.count, arrRightItems.count)
let widthOfItem : CGFloat = 30.0
let pading : CGFloat = 40
let aWidth : CGFloat = (self.navigationController?.navigationBar.frame.width)! - CGFloat(maxItemOnEitherSide) * widthOfItem * 2.0 - pading
let lblNavTitle = UILabel(frame: CGRect(x: 0, y: 0,
width: aWidth,
height: 40))
Case 1 : arrLeftItems.count = 1 and arrRightItems.count = 0.
Output :
Case 2 : arrLeftItems.count = 0 and arrRightItems.count = 1.
Hope above cases clear you out what we are expecting and what we are getting and the calculation that I wrote in first para i.e. titleview.x = rightItem.x - width.
Conclusion :
If rightBarItems have more items than leftBarItems then titleview will be in center, so you wont need to do anything but if leftBarItems have more items than rightBarItems then add blank items in right side to make it balance. It is weird for developers but seems like its the only solution.
Check the final output.
View Heirarchy
Output
If your navigation Item is part of a UINavigationController you could try
self.navigationController?.navigationBar.topItem?.leftBarButtonItem?.width ?? 0.0
Add my version code based on #dahiya_boy answers.
In my case, I have a custom button that has a more 30-width size. So, rather than multiply it by 30, I find a max from left and right items to find the max.
Below is the code:
func setCenterTitle(_ title: String) {
let navWidth = (navigationController?.navigationBar.frame.width).orZero
let leftItemsWidth = leftBarButtonItems.orEmptyArray.reduce(0) {
$0 + ($1.customView?.frame.width).orZero
}
let rightItemsWidth = rightBarButtonItems.orEmptyArray.reduce(0) {
$0 + ($1.customView?.frame.width).orZero
}
let maxItemsWidth = max(leftItemsWidth, rightItemsWidth)
let padding: CGFloat = 40
let labelWidth = navWidth - (maxItemsWidth * 2) - padding
let titleLabel = UILabel(frame: CGRect(x: 0, y: 0, width: labelWidth, height: 40))
titleLabel.text = title
titleLabel.textAlignment = .center
titleLabel.font = UIFont.boldSystemFont(ofSize: 16)
self.titleView = titleLabel
}
I'm having a problem with looping an object in Swift.
I want to declare the UITextfield as an instance variable so I can access it anywhere inside the class.
So if I put it inside the loop it works fine, but I put the variable of UITextField outside the loop, it doesn't show the first textfield in the view and the username textfield would be missing.
Here's my code
var placeHolderArr:[String] = ["Username", "Password"]
let loginField = UITextField() // <----- this one
override func viewDidLoad() {
super.viewDidLoad()
let logoHolder = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height / 2))
logoHolder.backgroundColor = self.utils.hexStringToUIColor(hex: "#ff8f00")
for index in 0...1 {
let height = index * 60
// When I declare the textfield variable in this line, it works fine.
loginField.frame = CGRect(x: 0 , y: Int((logoHolder.frame.maxY + 30) + CGFloat(height)), width: Int(self.view.frame.width - 80), height: 50)
loginField.placeholder = placeHolderArr [index]
loginField.font = UIFont.systemFont(ofSize: 15)
loginField.borderStyle = UITextBorderStyle.roundedRect
loginField.autocorrectionType = UITextAutocorrectionType.no
loginField.keyboardType = UIKeyboardType.default
loginField.returnKeyType = UIReturnKeyType.done
loginField.clearButtonMode = UITextFieldViewMode.whileEditing;
loginField.contentVerticalAlignment = UIControlContentVerticalAlignment.center
loginField.center.x = self.view.center.x
loginField.delegate = self
loginField.tag = index
innerY = Int(loginField.frame.maxY)
print("index\(index)" )
self.view.addSubview(loginField)
}
}
Please see the screenshot below
Textfield when declared inside the loop:
Textfield when declared outside the loop:
Obviously you use the same UITextField. Judt put initialization inside the loop
for index in 0...1 {
let height = index * 60
// When I declare the textfield variable in this line, it works fine.
loginField = UITextField()
loginField.frame = CGRect(x: 0 , y: Int((logoHolder.frame.maxY + 30) + CGFloat(height)), width: Int(self.view.frame.width - 80), height: 50)
loginField
And to use it later use array:
var fieldArr:[UITextField] = []
Then later:
fieldArr.append(loginField)
Summarise:
var placeHolderArr:[String] = ["Username", "Password"]
let loginFields:[UITextField] = []
override func viewDidLoad() {
super.viewDidLoad()
let logoHolder = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height / 2))
logoHolder.backgroundColor = self.utils.hexStringToUIColor(hex: "#ff8f00")
for index in 0...1 {
let loginField = UITextField()
let height = index * 60
// When I declare the textfield variable in this line, it works fine.
loginField.frame = CGRect(x: 0 , y: Int((logoHolder.frame.maxY + 30) + CGFloat(height)), width: Int(self.view.frame.width - 80), height: 50)
loginField.placeholder = placeHolderArr [index]
loginField.font = UIFont.systemFont(ofSize: 15)
loginField.borderStyle = UITextBorderStyle.roundedRect
loginField.autocorrectionType = UITextAutocorrectionType.no
loginField.keyboardType = UIKeyboardType.default
loginField.returnKeyType = UIReturnKeyType.done
loginField.clearButtonMode = UITextFieldViewMode.whileEditing;
loginField.contentVerticalAlignment = UIControlContentVerticalAlignment.center
loginField.center.x = self.view.center.x
loginField.delegate = self
loginField.tag = index
innerY = Int(loginField.frame.maxY)
print("index\(index)" )
self.view.addSubview(loginField)
loginFields.append(loginField)
}
}
When you declare the UITextfield subclass outside your loop, than every time when you set it up, you set up the same UITextfield instance. This means, you are overriding the first set of properties with the next one, every time you iterate on it.
Instead, lets create two instances, and set up both independently:
// declare this outside your loop
let usernameField = UITextField()
let passwordField = UITextField()
for (index, loginField) in [usernameField, passwordField].enumerated() {
// do your setup
}
You can create two properties:
let usernameField = UITextField()
let passwordField = UITextField()
and loop every text field like:
for (index, loginField) in [usernameField, passwordField].enumerated() {
//do what you need
}
I am trying to create 7 UILabel programmatically and I am not able to change the text of all UILabel.
let viewsCount = 2
let viewLblcount = 7
var messageForLbl = ["helo", "bhago", "futo", "bhensali" , "bhaaw bhaaw", "haha" ,"alladh"]
let floatValue = CGFloat(viewsCount)
let floatLbl = CGFloat(viewLblcount)
let scrollView: UIScrollView = UIScrollView(frame: CGRectMake(20, 30, 320, 250 * floatValue))
for i in 0 ..< viewsCount {
let views: UIView = UIView(frame: CGRectMake(0, 320 * CGFloat(i) + floatValue, self.view.frame.size.width - 40, 300))
views.backgroundColor = UIColor.grayColor()
views.tag = i + 1
for j in 0 ..< viewLblcount {
let label = UILabel(frame: CGRectMake(20, 40 * CGFloat(j) + floatLbl, self.view.frame.size.width - 100, 20))
let label2 = UILabel(frame: CGRectMake(10, 90 * CGFloat(j) + floatLbl, self.view.frame.size.width - 100, 30))
label.backgroundColor = UIColor.cyanColor()
label.text = "iOS LABEL TRY"
label2.backgroundColor = UIColor.magentaColor()
label2.text = "iOS LABEL TRY2"
label.tag = j + 1
label2.tag = j + 1
views.addSubview(label)
views.addSubview(label2)
scrollView.addSubview(views)
self.view!.addSubview(scrollView)
scrollView.contentSize = CGSizeMake(310, 390 * floatValue)
}
All the label is showing same text.
You have the text of the labels hardcoded on these lines:
label.text = "iOS LABEL TRY"
label2.text = "iOS LABEL TRY2"
I'm not exactly sure what text you want in each label, but I think you want to change it to:
label.text = messageForLbl[j]
Also, you can avoid a future bug by using Swift's enumerators (then you don't have to change viewLblcount when you change messageForLbl):
for value in messageForLbl.enumerate() {
label.text = value
}
Because you have hard coded the text
label.text = "iOS LABEL TRY"
I am attempting to output a list of an account's 'friends' by pragmatically creating and stacking labels. I have fetched the accounts' friends from a MySQL database (accessible via NSURL interacting with a PHP script) and loaded them into an array. The goal is to loop through the array and create a label that is positioned slightly below the previous one each iteration. The problem I have run into is when I pass a variable into the CGRectMake function to create the label, it will not accept the int because it is not of type "CGFloat". I feel like I have tried just about everything, but I can never cast the data type correctly.Here is my code:
import UIKit
class viewFriendsViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let friendsArray = ["billy", "joe", "bob", "jim"]
var inc = 0
for index in friendsArray {
let label: UILabel = UILabel()
let yPos: CGFloat = Float(inc * 10)
label.frame = CGRectMake(50, 50, 200, yPos)
label.backgroundColor = UIColor.blackColor()
label.textColor = UIColor.whiteColor()
label.textAlignment = NSTextAlignment.Center
label.text = "\(index)"
self.view.addSubview(label)
inc = inc + 1 // I have not been able to play with the label yet to determine how to move it's vertical position because I cannot run the program due to the casting error.
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
try this
var inc = 0
for index in friendsArray {
let label: UILabel = UILabel()
//type conversion is
let yPos = CGFloat(inc * 10)
label.frame = CGRectMake(50,yPos,200,50) // if you want to change the Y-Coodinates use in Y frame not in height
label.backgroundColor = UIColor.blackColor()
label.textColor = UIColor.whiteColor()
label.textAlignment = NSTextAlignment.Center
label.text = "\(index)"
self.view.addSubview(label)
inc = inc + 1
}
the above choice is not work try this
var inc : CGFloat = 0
for index in friendsArray {
let label: UILabel = UILabel()
label.frame = CGRectMake(50,inc,200,50) // if you want to change the Y-Coodinates use in Y frame not in height
label.backgroundColor = UIColor.blackColor()
label.textColor = UIColor.whiteColor()
label.textAlignment = NSTextAlignment.Center
label.text = "\(index)"
self.view.addSubview(label)
inc = inc * 10 // inc + 10
}
You should take advantage of the new notation for CGRect in swift instead of using legacy c macros, these allow for usage with Int, Double and Float:
CGRect(x: 50, y: 200, width: 20, height: 40)
Note that these frames are now created using standard swift init functions for structs.
I've tested it with CGFloat() instead of Float() and it works:
var inc = 0
var ypos: CGFloat = CGFloat(inc * 10)
var rect: CGRect = CGRectMake(50, ypos, 200, 200)
Also note you are currently using your ypos at the position of the height. Remember it is
CGRectMake(<xPos>, <yPos>, <width>, <height>)