I am a total newby to xCode and Swift so please excuse me if this question is silly.
I am trying to update 2 UILabels and a UIImageView by using the sender.currentTitle of the button pressed.
If a user presses the 'Honduras' button then I want to populate the 2 UILabel with it's corresponding information and the UIImageView with its corresponding image file.
I have the first UILabel working and the UIImageView working but cannot find a way to populate the 2nd UILabel with its corresponding text (which is stored in a constant).
UILabel 1 is called #IBOutlet weak var countryLabel: UILabel!
UILabel 2 is called #IBOutlet weak var peopleLabel: UILabel!
UImageView is called #IBOutlet weak var peopleUIImageView: UIImageView!
The information/file name I want to pass into these 3 are called:
"Honduras"
let peopleHondurasText = "The Lenca"
"peopleHonduras.png"
I have the UILabel 1 working like this:
countryLabel.text = sender.currentTitle
I have the image working by calling this func:
func findCountryImages() {
peopleUIImageView.image = UIImage(named: "people\(countryLabel.text! .filter { !" ".contains($0) }).png")
}
and I am trying to call the constant "peopleHondurasText" like I did the UIImage but it isn't working.
Here is my very amateur code:
peopleLabel.text = "people\(countryLabel.text! .filter { !" ".contains($0) })Text"
Where this:
"people\(countryLabel.text! .filter { !" ".contains($0) })Text"
Should be equal to the constant named:
peopleHondurasText
I want to be able to do this so if a user clicks on any country button it will populate those 2 UILabels and UIImageViews with that countries text and images.
I know I must be doing something fundamentally incorrect or maybe going about this complete in the wrong but if anyone could let me know either how to pass the constant name into the UILable
or tell me that you cannot do this and I should try something different, that would be greatly appreciated.
How come you don't just do:
peopleLabel.text = peopleHondurasText
Related
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
This question already has answers here:
How to add a button with click event on UITableViewCell in Swift?
(4 answers)
Closed 1 year ago.
I have a UITableView with cells, every cell have information of products, the name of the product and the Id of the product. Every cell has a button that drives you to another screen with more details of the product.
My problem is that when I selects a cell, I have obtain the name and id of the product that belongs to the selected cell thanks to didSelectRowAtIndexPath, but when I touch the button inside the cell I don't trigger didSelectRowAtIndexPath and I can't obtain the id of the product, because of this I can't go to the next screen and show the information related to the selected product.
What could I do?
The question I will ask you which will help solve this is:
Are you using IBAction to transition as the action trigger for the button?
If Yes, then the IBAction will sit under the UITableViewCell which should contain IBOutlet for the UILabels holding the value of name, id and product information.
For example:
class SampleCell: UITableViewCell {
#IBOutlet var nameLabel: UILabel!
#IBOutlet var idLabel: UILabel!
#IBOutlet var informationLabel: UILabel!
#IBAction func action(button: UIButton) {
// you can obtain your information once the button is triggered before navigating
let id = self.idLabel.text
let name = self.nameLabel.text
let information = self.informationLabel.text
// navigate to new screen using delegate protocols
}
}
if you are not using IBOutlets and IBActions as follows, then I will suggest you use them, and create a custom TableViewCell for the product cell. It is the easiest way to access your cell information
I am accessing a Realm database to load values in my iOS app. The first one works fine. I have a UIViewController with UITextFields. The big picture is that i:
Define the outlets in the ViewController and connect them to the mainstoryboard UITextFields. There are three fields
I set up an array and load the results of the Realm query from a PersonData.swift data model. Three properties defined in the swift file.
In viewDidLoad I call the function to loadPersonData.
The first thing in the loadPersonData func is to put the realm.objects including three properties into the three fields that are defined by the Outlets at the top of the ViewController.
They load perfectly, are editable, and I can save the values of the data entry from the screen to the Realm database with a Realm modify. I can show you this code if you want to see it.
This is all working fine. Now my problem. My next View is a UITableViewController, with prototype cell, and three UILabels in each single cell row. This code has in the past used an Array for testing and that worked fine to load sample data back to the rows. I want to now read Realm data and scroll up and down with the three fields in each row. Later, when I select one,I will expose in another View all of the properties of that object called Year which is approximately 10 properties or UITextFields that can be edited.
I was told to build a subclass for the protype cell that will be a sub to the UITableViewCell.
class BYMyCell: UITableViewCell {
I put the Outlets for the three UILabels from the prototype cell into the BYMyCell.swift subclass. These outlets are connected to the UILabels defined in the prototype cell.
I saw one suggestion about putting the same outlets in the first businessYearViewController where all the row support functions were located. I was told to add the = nil to these outlets.
#IBOutlet weak var yearLabel: UILabel! = nil
#IBOutlet weak var descriptionLabel: UILabel! = nil
#IBOutlet weak var startingDateLabel: UILabel! = nil
Now when I try to move the Results of the Realm query from the three properties to the three Labels there appears to be nil in all the fields. I can see the data come into my businessYearViewController where I make the query, but I am having trouble putting the data into the Outlets in the BYMyCell.swift data model for exposure on the view/screen.
If I should post my two files, I will try to put them in a response. Thanks for your help. I'm pretty sure this has something to do with my lack of knowledge of processing TableViewController and prototype cell coordination. My rows are simple. One row, three labels. I will also have an add button at the top right corner and the ability to edit the fields in another View for data entry and changes.
Edited one hour later with information. This is my loadBusinessYear func.
func loadBusinessYearData() {
businessYearArray = realm.objects(YrData.self)
print(businessYearArray!.count)
print(businessYearArray?[0])
if businessYearArray!.count > 0 {
yearLabel.text = businessYearArray?[0].year
descriptionLabel.text = businessYearArray?[0].yearType
startingDateLabel.text = businessYearArray?[0].startingDate
} else {
yearLabel.text = "Sample Name"
descriptionLabel.text = "Sample .com"
startingDateLabel.text = "Sample Date"
}
}
The two print statements at the top give you the 1 for the count and the object properties as Optionals.
1
Optional(YrData {
ydID = 0;
year = 2020;
yearType = Business Open;
startingDate = 12/28/2019;
firstWeekEndDate = 01/03/2020;
lastWeekEndDate = 01/03/2021;
firstQtrTotal = 520;
secondQtrTotal = 520;
thirdQtrTotal = 520;
fourthQtrTotal = 520;
leapYearExtraWeek = 40;
yearContains53Weeks = 1;
laborReporting = List<LaborReportData> <0x600000a15290> (
);
expenseAccounting = List<ExpenseAccountData> <0x600000a15440> (
);
})
The data subclass is BYMyCell swift file.
import UIKit
class BYMyCell: UITableViewCell {
#IBOutlet weak var yearLabel: UILabel!
#IBOutlet weak var descriptionLabel: UILabel!
#IBOutlet weak var startingDateLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
I know that this question may sounds duplicate, but looking at the several answer, nothing is working for me yet.
Basically I have a Quizz App, a question is shown and the user needs to fill several UITextFields to answer the question (i.e. if the answer is VENICE, 6 UITextFields will be shown, 1 per letter).
It was able to detect one character in the UITextFields and once the user hits a key it will jump to the following UITextField. I use the tag of the UITextField and the method becomeFirstResponder.
The problem is that I will like to detect the backspace when a UITextField is empty so I will jump to the previous UITextField.
I have tried this solution from Jacob Caraballo (Detect backspace in empty UITextField) but I am not sure, how to use it with my existing UITextField.
For example, I have tried:
// #IBOutlet weak var textField1: UITextField!
#IBOutlet weak var textField1:MyTextField!
But calling the delegate
textField1.myDelegate = self
It crashes
I also notice, that using the Jacob's solution I won't be able to check which UITextField was used as the func textFieldDidDelete() doesn't not have an UITextField as parameter and I will need to check its tag i.e.
If textField.tag == 5 {
textField4.becomeFirstResponder()
}
Any help on this please?
If you use Jacob's solution, the deleteBackward method will be called with the current UITextField instance. So you can add a protocol to that UITextField class and pass it back to your view.
Something like this:
protocol MyTextFieldDelegate: class {
func backwardDetected(textField: MyTextField)
}
class MyTextField: UITextField {
weak var myTextFieldDelegate: MyTextFieldDelegate?
override func deleteBackward() {
super.deleteBackward()
self.myTextFieldDelegate?.backwardDetected(textField: self)
}
}
enter image description here
Please tell me what kind of code to write
I suppose you've already created the reference for the textbox as TextView. Now you need to create a new IBOutlet for the label. Once you have the reference to the label you can get the text value from the textview and show it in the label.
#IBAction func display(_sender) {
self.labelView.text = self.TextView.text
//if you want to clear the textview
self.TextView.text = ""
}
Create outlet for your label
#IBOutlet weak var yourlabel: UILabel!
On Button Action right code to set the value to label.
#IBAction func display(_sender) {
yourlabel.text = self.TextView.text
}