Variable name in a loop using an integer - swift

I want to change the text of a lot of labels. All my labels are named LabelName1, LabelName2, LabelName3.
How can I edit my labels with one loop like this:
for i in 1..10 {
LabelName(i).Text = String(some text, the some for each label)
}

You should store all of your UILabels in an array and change the text for all of them like this:
for label in labelArray {
label.text = String(some text, the some for each label)
}

Alternatively to #toddg fine answer, you could assign a specific tag to the labels and loop through the subviews:
// loop through subviews and update all UILabels with a tag property of 4
for view in self.subviews as [UIView] {
if let label = view as? UILabel {
if label.tag == 4 {
label.text = String(some text, the some for each label)
}
}
}
The advantages to this is no arrays are needed, and you can be as specific or generic as desired.

Related

UICollectionViewListCell Accessory TopTrailing Placement

iOS 14 introduced a bunch of advancements for UICollectionView including the new UICollectionViewListCell. Using the defaultContentConfiguration, you can add accessory views to the cell. I'm looking to recreate an iMessage conversation row (mail is also close) where the date label is in the top trailing corner. Is there anyway to do this using the default configuration? Having to create a custom cell seems like overkill just for this.
Here is what I currently have.
let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, Int> { cell, indexPath, item in
var content = cell.defaultContentConfiguration()
content.text = "Title"
content.secondaryText = "This is the body of the message and it's really long. I want to see where it finally truncates because thats what it should do eventually you know?"
content.secondaryTextProperties.numberOfLines = 2
content.image = UIImage(systemName: "star")
let label = UILabel()
label.text = "4/26/7"
label.textColor = .secondaryLabel
label.font = .preferredFont(forTextStyle: .caption1)
let customAccessory = UICellAccessory.CustomViewConfiguration(
customView: label,
placement: .trailing(displayed: .always))
cell.accessories = [.customView(configuration: customAccessory)]
cell.contentConfiguration = content
cell.tintColor = .tertiaryLabel
}
Here is my desired result
Here is mail for another example
The default UICollectionViewListCell has limited customization possibilities.
Your best shot is with a custom UICollectionViewCell subclass. You will instead have the cell registration register your custom class, and dequeue cells the same way you would dequeue a built-in UICollectionViewListCell class object.

UITextField to change size to fix text content

I have a custom UITableViewCell with a UITextField. I have the cell in a tableview inside my view controller.
let cellText : UITextField = {
let secureText = UITextField()
secureText.isSecureTextEntry = true
secureText.isUserInteractionEnabled = false
return secureText
}()
I want to change the size of the textField based on the amount of text that is inside the text field.
note* I do need the this to be a UITextField field because I want the text to go through as a isSecure text.
try this (when you're done editing):
textField.frame.size.width = textField.intrinsicContentSize.width

How can I animate the change of the navigation bar title

I am looking for a way to run a custom CAAnimation on the UINavigationBar title.
More precisely, I am looking for a way to access the label which displays navigationItem.title and run animations on that.
It is certainly possible to manually create a UILabel and set the navigationBar.titleView accordingly.
This however seems to be too much effort for a hopefully simple problem. Plus, it will not work well with large titles on the UInavigationBar.
The title text is accessible as topItem.text. There is no way to directly access the label which is displaying this text.
So if you want to animate this label, you first have to search for it in the subview of the NavigationBar.
Then, you can apply animations on this label.
See below for an example that fades in the new title from the right.
/// Fades in the new title from the right
///
/// - Parameter newTitle: New title to display on the navigation item
func animateTitle(newTitle: String) {
// Title animation code
let titleAnimation = CATransition()
titleAnimation.duration = 0.25
titleAnimation.type = CATransitionType.push
titleAnimation.subtype = CATransitionSubtype.fromRight
titleAnimation.timingFunction = CAMediaTimingFunction.init(name: CAMediaTimingFunctionName.easeInEaseOut)
// Find the Label which contains the topitem title
if let subviews = navigationController?.navigationBar.subviews {
for navigationItem in subviews {
for itemSubView in navigationItem.subviews {
if let largeLabel = itemSubView as? UILabel {
largeLabel.layer.add(titleAnimation, forKey: "changeTitle")
}
}
}
}
navigationItem.title = newTitle
}

Swift - Custom cell width and height for textlabel and detailTextLabel

I wanna manage the long text in textlabel and detailtextlabel for the cells in UITableview because if the textlabel has a long text the detailedtextlabel truncate with "..." and viceversa.
Here's the problem:
So I wanna know if there's a way to manage the space between textlabel and detailtextlabel so there's no truncate and give them more lines. I tried with:
...
if tableData[indexPath.row].clave.count > 6 {
cell?.detailTextLabel?.numberOfLines = 5
cell?.textLabel?.numberOfLines = 5
} else {
cell?.detailTextLabel?.numberOfLines = 1
}
cell?.textLabel?.text = nueva_cadena_string
cell?.detailTextLabel?.text = tableData[indexPath.row].clave
cell?.textLabel?.textColor = UIColor.brown
cell?.textLabel?.font = UIFont.boldSystemFont(ofSize: 15.0)
cell?.textLabel?.lineBreakMode = .byWordWrapping
return cell!;
But it doesn't work very well, it seems to give them just 2 lines, not 5 and I can't change the width for the textlabel and detailtextlabel.
Try making your cell custom as this:
Try setting the tableviews row dimension to automatic
yourTableView.rowHeight = UITableViewAutomaticDimension
yourTableView.estimatedRowHeight = 80.0
try setting both textlabels number of lines either in the storyboard or in code to 0 as then they will all have the amount of lines they need.
You can subclass UITableViewCell and override the layoutSubviews() method. You will need to change the layout of textLabel and detailTextLabel there. Remember that these elements lie inside contentView, not in the cell itself.
But better you add two custom labels on the Storyboard and configure them as you want. It's easier.

Multiple UICollectionView Data Sources in One UIViewController

I have a question about the implementation.
My users will be able to select from a dropdown what they want to see in the collection view. Depending on the choice, the dataset and potentially section/cell types will change.
Should I have one UICollectionView with all of the cells registered and based on the users choice modify my cellForItemAt?
Or should I have a UICollectionView per choice and then swap them depending on the choice?
What is the best and more professional implementation?
If the cells being displayed are similar in nature (they have the same structure of data aka picture, text, description, name, etc) then you should use one re-useable cell.
Having one cell makes your code much cleaner. You can also then set an observable property inside your cell that you set with the data. Pass the data to cell and then inside the cell class, it will be responsible for laying out the code.
let cell = someDequeuedCell
cell.data = somedata
return cell
Then inside the cell class,
var data: SomeData? {
didSet {
//Determine data and layout cell
if data == 'apple' {
//Layout apple cell
} else if data == 'orange' {
//Layout orange cell
} else {
//Layout other cell
}
}
}
This approach is very commonly used, however if each cell varies more than just data being changed. You should register multiple different cells for each datatype.
Inside the collectionView
if dataType == "apple" {
let cell = appleCell
cell.data = someData
return cell
} else if dataType == "orange" {
let cell = orangeCell
cell.data = someData
return cell
} else {
let cell = otherCell
cell.data = someData
return cell
}