UITextField wrong content width when isSecureTextEntry property set to true - ios

I have two UITextFields configured like that:
let yellowPasswordTextField = UITextField()
view.addSubview(yellowPasswordTextField)
yellowPasswordTextField.placeholder = "Type"
yellowPasswordTextField.isSecureTextEntry = true
yellowPasswordTextField.backgroundColor = UIColor.yellow
yellowPasswordTextField.topToSuperview(offset: 30) // TinyConstraints api
yellowPasswordTextField.leftToSuperview()
yellowPasswordTextField.text = "mmmmmm"
let greenTextField = UITextField()
view.addSubview(greenTextField)
greenTextField.placeholder = "Type"
greenTextField.isSecureTextEntry = false
greenTextField.backgroundColor = UIColor.green
greenTextField.topToSuperview(offset: 60)
greenTextField.leftToSuperview()
greenTextField.text = "mmmmmm"
Please notice that both are configured exactly the same (including text), the only difference is that the first one has isSecureTextEntry property enabled while the second one has this property disabled.
And here is the result layout:
Why first UITextField has width that is exactly the same like for text field with isSecureTextEntry disabled (the one below)? Is there any way to force first text field to adjust its width to actual content - bullets replacing original text?
It's problematic because I would like to add rightView for showing/hiding password just after textfield content.

Related

How to implement Material chips in UITextfield using Swift 4

I have needed this type of chips UITextfield with a cancel button
let chipView = MDCChipView()
chipView.titleLabel.text = "Furkan#vijapura.com"
chipView.setTitleColor(UIColor.red, for: .selected)
chipView.sizeToFit()
chipView.backgroundColor(for: .selected)
self.view.addSubview(chipView)
self.userAdd.addSubview(chipView)
You can achieve this by creating a collectionView with multiple cells you can define the layout of each cell and your last cell will contain a text field.
Please let me know if you need a reference code for doing this.
Supposing that you have installed via pods:
Text Field with Floating Placeholder
let textFieldFloating = MDCMultilineTextField()
scrollView.addSubview(textFieldFloating)
textFieldFloating.placeholder = "Full Name"
textFieldFloating.textView.delegate = self
textFieldControllerFloating = MDCTextInputControllerUnderline(textInput: textFieldFloating) // Hold on as a property
Text Field with Character Count and Inline Placeholder
// First the text field component is setup just like a UITextField
let textFieldDefaultCharMax = MDCMultilineTextField()
scrollView.addSubview(textFieldDefaultCharMax)
textFieldDefaultCharMax.placeholder = "Enter up to 50 characters"
textFieldDefaultCharMax.textView.delegate = self
// Second the controller is created to manage the text field
textFieldControllerDefaultCharMax = MDCTextInputControllerUnderline(textInput: textFieldDefaultCharMax) // Hold on as a property
textFieldControllerDefaultCharMax.characterCountMax = 50
textFieldControllerDefaultCharMax.isFloatingEnabled = false
Also If you want to follow a Git Project Use: https://github.com/Skyscanner/SkyFloatingLabelTextField

How to change an UILabel's text when an UIStepper tapped programmatically in Swift 4, if they are both in an UITableViewCell?

Swift 4: I have a static cell (grouped style). I just add an UILabel and an UIStepper to the cell. Now I would like to change the UILabel's text, when I tap the UIStepper. Just like the picture:
Here are my codes:
if indexPath.section == 0 {
cell.textLabel?.text = "\(first[indexPath.row])"
let step = UIStepper()
let label = UILabel()
func labelValueChanged(sender:UIStepper!) {
label.text = "\(Int(step.value))"
}
cell.addSubview(step)
step.translatesAutoresizingMaskIntoConstraints = false
step.centerYAnchor.constraint(equalTo: cell.centerYAnchor).isActive = true
step.widthAnchor.constraint(equalToConstant: 94).isActive = true
step.heightAnchor.constraint(equalToConstant: 29).isActive = true
step.rightAnchor.constraint(equalTo: cell.rightAnchor, constant: -30).isActive = true
step.addTarget(self, action: #selector(labelValueChanged), for: .valueChanged)
cell.addSubview(label)
label.text = "0"
label.translatesAutoresizingMaskIntoConstraints = false
label.centerYAnchor.constraint(equalTo: cell.centerYAnchor).isActive = true
label.widthAnchor.constraint(equalToConstant: 50).isActive = true
label.heightAnchor.constraint(equalToConstant: 21).isActive = true
label.rightAnchor.constraint(equalTo: cell.rightAnchor, constant: -124).isActive = true
}
There will be an error if the labelValueChanged function was added inside of the cell: Argument of '#selector' cannot refer to local function 'labelValueChanged(sender:)'
But if the labelValueChanged function was added outside of the cell, the label and UIStepper's value will be unavailable.
Is there any way to make it happen? Any suggestions would be appreciated. Thanks.
Is there any way to make it happen?
One way to do it is to use the stepper's tag property to store the cell's row number. The view controller can then get the stepper's tag and know what row is affected. That's not ideal, though, because it doesn't really work well for tables with multiple sections.
There will be an error if the labelValueChanged function was added inside of the cell: Argument of '#selector' cannot refer to local function 'labelValueChanged(sender:)'
I can't quite tell why you're having this problem, but you can certainly add an IBAction method to a custom table cell class, set the stepper's target to the cell, and set the stepper's action to that method. And you don't need to set the target and action programmatically -- you can configure them in the storyboard editor. A good strategy would be to have the cell then delegate the real work to some controller object, probably the view controller. Setting the stepper's target to the cell lets the cell call a method in the controller that includes more parameters than just a simple action (which only has a sender parameter), so you can pass along the row and section, how the stepper value changed, and anything else you might need.

Having textfield background transparent, but placeholder text opaque

Is it possible to have a textfield's placeholder text opaque while its background is set to be transparent, eg. if I choose some background color, and set alpha to some value, like this:
the placeholder text becomes transparent as well. But I want it opaque. So, is this achievable, preferably using storyboard ? Or at least through the code.
If it is unclear what I am trying to achieve, just let me know , and I'll post an image with an example.
You can set the color's transparency instead of the UITextField's alpha. Open the color drop down and select "Other". A color picker will open up. At the bottom of the color picker you can change the opacity.
In Swift you can obtain the placeholder element with:
let placeHolder = textField.value(forKey: "placeholderLabel") as! UILabel
placeHolder.textColor = .blue
placeHolder.isOpaque = true
and make all customizations you prefeer..
You can set the UITextView.background = .clear
I'm providing a little more code so it'll be easier to setup it programmatically, this is a ready-to-use sample.
private lazy var textField: UITextView = {
let textField = UITextView()
textField.translatesAutoresizingMaskIntoConstraints = false
textField.font = UIFont.systemFont(ofSize: 14)
textField.isEditable = false
textField.textAlignment = .center
textField.isScrollEnabled = false
textField.backgroundColor = .clear // this is the line that answer you question
textField.text = """
People with these symptoms may have COVID-19:
Fever of chills, cough, shortness of breath or
difficulty breathing, fatigue, muscle or body aches,
headache, new loss of taste and smell, sore throat,
congestion or runny nose, nausea or vomiting,
diarrhea
"""
return textField
}()
Just remember to set the constraints and add the subview into your superview .addSubview(TextField)

intrinsically sizing from core data (swift 3)

I have a name label in a cell that is intrinsically sized so that the left anchor of the time label may always be 5 pixels from the left anchor of the name label. However when I introduce names from core data, it takes the initial setup name and uses that name to intrinsically size the name label frame.
Here is where I create the label view.
let nameLabel: UILabel = {
let nlabel = UILabel()
nlabel.text = "Barack Obama"
nlabel.font = UIFont.boldSystemFont(ofSize: 12)
nlabel.textAlignment = .left
nlabel.frame.size = nlabel.intrinsicContentSize
nlabel.backgroundColor = UIColor.blue
print("nlabel frame \(nlabel.frame.size)")
return nlabel
}()
nlabel.text for each cell is equal to cell?.friend?.name
I am successfully able to load the names into the cell however the frame is still sized as if nlabel.text was equal to the first nlabel.text.
Any suggestions?
Assuming you are using Auto Layout, remove this line:
nlabel.frame.size = nlabel.intrinsicContentSize
And add this line:
nlabel.translatesAutoresizingMaskIntoConstraints = false
With Auto Layout, you must not set the frame size yourself.
You are giving the same size to every label you create. The size is not going to change just because you change the text it contains.
Labels have intrinsic size, but when you create labels in code, not the storyboard, you need to set translatesAutoResizingMaskIntoConstraints to false in order for this to work. When you create labels in the storyboard, this is done for you automatically.
For more info, see https://developer.apple.com/reference/uikit/uiview/1622572-translatesautoresizingmaskintoco?language=objc

Multi-line editable piece of text: editable UILabel?

I am trying to create a large plot of editable text but there seems to be 1 option: using a small UITextField.
I know UILabels can be big and wide but I do not know how to make an editable UILabel.
I experimented with UILabel properties and the .layer method but nothing seems to be really working. Anybody have a recommendation as to what I should do?
To summarize, I am looking for a multi-line editable piece of text.
UITextView for the win!!
UITextViews allow for multiple line manipulation of texts and if you use the UITextViewDelegate, it can provide for methods that allow specific things when the textView is clicked on, etc...!
With a UITextView you can provide a specific amount of lines (if you only want 3, you can specify it) and also provide hyperlinks, if need be.
Here is an example I have (changed a little) to show an example for ya...
let textBox:UITextView = UITextView(frame: CGRect(x: firstBox.frame.width*0, y: firstBox.frame.height*0.375, width: firstBox.frame.width*1, height: firstBox.frame.height*0.5))
textBox.backgroundColor = UIColor.clearColor()
let websiteName = "http://stackoverflow.com/posts/38035564"
textBox.text = "SO is an awesome coding site! Please visit\n\(websiteName)"
//No need to set number of lines, it will auto set to as many as needed!
textBox.editable = false
textBox.selectable = true
//Register the hyperlink
textBox.dataDetectorTypes = UIDataDetectorTypes.All
textBox.textColor = UIColor.grayColor()
//Change only the hyperlink part
let textRange = NSMakeRange(textBox.text.characters.count-websiteName.characters.count, websiteName.characters.count)
let style = NSMutableParagraphStyle()
style.alignment = NSTextAlignment.Center
let attributedText = NSMutableAttributedString(string: textBox.text, attributes: [NSFontAttributeName:UIFont(
name: (textBox.font?.fontName)!,
size:13/15*fontSize)!,
NSParagraphStyleAttributeName: style])
attributedText.addAttribute(NSUnderlineStyleAttributeName , value:NSUnderlineStyle.StyleSingle.rawValue, range: textRange)
textBox.attributedText = attributedText
firstBox.addSubview(textBox)

Resources