The placeholder text does show the triple points to cut off the text.
The text doesn't even take half of the textfield width, and the three points are longer than the text. Is there a way to go inside the field and adjust the threshold to avoid the cutoff?
I do know the programatic way, and use that for the moment, to resize the placeholder tekst, till it fits.
let labelKeyPath: String = "_placeholderLabel"
var label : UILabel = self.Distance.value(forKeyPath: labelKeyPath) as! UILabel
label.adjustsFontSizeToFitWidth = true
label = self.FocalLength.value(forKeyPath: labelKeyPath) as! UILabel
label.adjustsFontSizeToFitWidth = true
Herby I do add some images of the current IB settings and results. Please keep adding points to let me show the current and future images embedded, thank you.
The IB view, settings and app result
Alternative you can create your own UITF subclass and override:
open func placeholderRect(forBounds bounds: CGRect) -> CGRect
You can customize the textfield to fix you issue. put this CustomTextField in your Storyboard textfield class type. here am setting minimum scaling factor to 0.3. that helps to fix the ...
class CustomTextField: UITextField {
override func layoutSubviews() {
super.layoutSubviews()
for subview in subviews {
if let label = subview as? UILabel {
label.minimumScaleFactor = 0.3
label.adjustsFontSizeToFitWidth = true
}
}
}
}
You should change Autolayouts Constraints with leading, center vertically with Distance and horizontal space with the Distance.
You can also wrap up text with resize the textfield using minimum font size.
Related
I'm using TextField in my app. I made it to wrap the content.
The problem is when the user types a long text the TextField edges glides out of the layout and make some of the view invisible.
is there a way to disable it to expend when it reaches to the layout edges?
The best thing to do is to change your UITextField to a UITextView. Here's a function that I like to use quite a lot for this autoresize technique that you'll see in the likes of Apples iMessage:
func containerViewHeight() {
let size = textView.sizeThatFits(CGSize(width: textView.frame.size.width, height: CGFloat.greatestFiniteMagnitude))
containerView.heightAnchor.constraint(equalToConstant: size.height + 24)
self.textView.setContentOffset(.zero, animated: false)
}
You'll want to call this function initially inside of your viewDidLoad:
override func viewDidLoad() {
self.containerViewHeight()
}
As well as that, you'll want to conform to the UITextViewDelegate methods by subclassing it at the top of your file like so:
class YourViewController: UIViewController, UITextViewDelegate
Once you add this AND you have used self.textView.delegate = self inside of your viewDidLoad:
override func viewDidLoad() {
self.textView.delegate = self
}
you'll then be able to use the textViewDidChange method for that textView, so the final thing you'll want to add in your class is this:
func textViewDidChange(_ textView: UITextView) {
self.containerViewHeight()
}
Your textField probably doesn't have a fixed width.
Just put a width constraint to your textField in your storyboard so it will always have the same width, no matter if the text is too long.
Edit : if you want a maximum width, you can add 2 width constraints to your textField. One for minimum width and one for maximum width. This way the width of your textField will vary between 100 and 200, depending on the text it contains.
Minimum width constraint :
Maximum width constraint :
I am using TextField by using Material Library. That's what the default implementation(Divider is under the Text Area only).
Is there any way to put the divider under the LeftView/Image and decrease the gap between Image and Text (like this).
Any help will be appreciated.
this could be the solution for your problem.....
let leftView = UIImageView()
leftView.image = Icon.phone?.tint(with: Color.blue.base)
textField.leftView = leftView
textField.leftViewMode = .always
When the leftView is laid out it sets the divider's edge inset equal to it's (the leftView) width. So you're going to need to change that. I am subclassing TextField, so I just overrode layoutSubviews.
override func layoutSubviews() {
super.layoutSubviews()
dividerContentEdgeInsets.left = 0
}
I have a UITextView that contains text that may range from a few words to a lot of words.
While using the app, the text view has a fixed height and scrolling is enabled so the user can view any potentially long text.
However, the user is allowed to "share" the screen using the native share features. During this process, I take a screenshot of the screen to use for the image, along with a few other added UI elements. Since you can't scroll a screenshot, I disabled the UITextView's scrolling ability and attempt to shrink the font of any long text, while increasing the font of any small text so that the UITextView is filled as best as possible.
This use to work on older versions of iOS, but iOS 9 seems to have some issues and now it cuts off some of the text:
One side note, this view is built in a XIB file and uses autolayout.
override func awakeFromNib() {
super.awakeFromNib()
self.translatesAutoresizingMaskIntoConstraints = false
if UIDevice.iPad() || UIDevice.iPadPro() {
bobbleheadViewWidthConstraint.constant = 300.0
bobbleheadViewHeightConstraint.constant = 600.0
self.updateConstraintsIfNeeded()
self.layoutIfNeeded()
}
speechBubbleView.roundCornersWithRadius(5.0)
}
class func shareViewForQuote(quote: Quote) -> BTVShareView? {
if let shareView = UINib(nibName: "BTVShareView", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as? BTVShareView {
shareView.bobbleheadView.image = UIImage(named: quote.character!.name!.stringByReplacingOccurrencesOfString(" ", withString: "-"))
shareView.textView.text = quote.text
shareView.textView.font = UIFont.systemFontOfSize(60.0)
// Re-size quote text
shareView.updateTextFont()
return shareView
}
return nil
}
func updateTextFont() {
let minFontSize: CGFloat = 1.0
var currentFontSize: CGFloat = 100.0
while (currentFontSize > minFontSize && textView.sizeThatFits(CGSizeMake(textView.frame.size.width, textView.frame.size.height)).height >= textView.frame.size.height) {
currentFontSize -= 1.0
textView.font = textView.font!.fontWithSize(currentFontSize)
}
}
So a better solution was to just use a UILabel for the share screen, since I don't need a UITextView anyways.
Still curious what the proper way to adjust font size to fit text to UITextView would be though...
In Swift, i have a UITextField on a table view cell, and when it's text becomes too long I would like the font size to decrease. I want to make it very clear that I am talking about a UITextField, not a UILabel or a UITextView. The reason I say this is because I have seen this question pop up several times and the answers were all based on UILabel instead of UITextField.
I hoped, that can be done in IB, where i did this settinngs of Min Font Size and ajust to fit, but this didnĀ“t change anything:
Is there another way to resolve this?
extension UITextField {
internal func resizeText() {
if let text = self.text{
self.font = UIFont.systemFontOfSize(14)
let textString = text as NSString
var widthOfText = textString.sizeWithAttributes([NSFontAttributeName : self.font!]).width
var widthOfFrame = self.frame.size.width
// decrease font size until it fits
while widthOfFrame - 5 < widthOfText {
let fontSize = self.font!.pointSize
self.font = self.font?.fontWithSize(fontSize - 0.5)
widthOfText = textString.sizeWithAttributes([NSFontAttributeName : self.font!]).width
widthOfFrame = self.frame.size.width
}
}
}
}
Based on the answer I linked, I created an extension to UITextField that automatically resizes text - to have it properly resize the text each time, it needs to be called in a number of locations:
override func drawRect(rect: CGRect) (I haven't found a better spot to call this as you have to wait until its bounds are set and the TVC lifecycle gets confusing)
textField(textField: UITextField, shouldChangeCharactersInRange...
I have a UILabel with more than one line:
let serviceDescription: UILabel = UILabel() serviceDescription.text =
"some very long text..."
serviceDescription.numberOfLines = 0
serviceDescription.sizeToFit()
self.contentView.addSubview(serviceDescription)
Then I add some autolayout constraints:
serviceDescription.snp_makeConstraints { (make) -> Void in
make.top.equalTo(self.contentView_snp_top).offset(24)
make.left.equalTo(self.contentView).offset(20)
make.right.equalTo(self.contentView).offset(-20)
}
Now I want to compute the size this label would need on the screen so I did:
let newSize: CGSize = serviceDescription.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
println("serviceDescription size: \(newSize)")
The result is:
(3408.0, 95.5)
I did all the preceding commands in viewDidLoad().
How do I get the correct size of the label on screen?
You don't need to calculate the height, the label knows its height after it has laid itself out,
override func viewDidLoad() {
super.viewDidLoad()
println(label.frame.height) // 21
label.text = "Some long text to make the text go over more than one line"
label.layoutIfNeeded()
println(label.frame.height) // 101.5
}