0

I tried to rebuild the UITextField from Apple's "Phone" app.

I built a numpad where each button triggers a certain value (0-9, #, *) and appends it to the text field's text.

The textAlignment property is set to center. However, when inserting numbers, the text field does not scroll or move to the last character. F.ex., if there're more than 10 numbers and I'm adding the eleventh number, that one won't be displayed because it's off the screen.

Apple handles this issue by first shrinking the font size and then scrolling to the cursor position.

Is there a simple trick to achieve the same result?

I attached two images.

enter image description here

enter image description here

enter image description here

j3141592653589793238
  • 1,810
  • 2
  • 16
  • 38

5 Answers5

0

Use this example. Sets cursor and scrolls to the end of UITextField. Because of you do operations with UI, you have to do it in main thread

DispatchQueue.main.async {[weak self] in
     self?.textField.becomeFirstResponder() // to focuse on this UITextField
    let newPosition = self?.textField.endOfDocument  ?? UITextPosition()
    self?.textField.selectedTextRange = self?.textField.textRange(from: newPosition, to: newPosition)
}
Agisight
  • 1,778
  • 1
  • 14
  • 15
0

You need to set the minimum font size for the text view in storyboard and check the adjust to fit check box below it.

enter image description here

Pooja Kamath
  • 1,290
  • 1
  • 10
  • 17
0

why using a textfield instead of using a uilabel?

This can easily fixed with

label.adjustsFontSizeToFitWidth = true
label.textAlignment = .center
label.setFillSuperview(withPadding: UIEdgeInsets(top: 0, left: whatYouNeed, bottom: 0, right: whatYouNeed))

and add extension to UIView

extension UIView {
    func setFillSuperview(withPadding padding: UIEdgeInsets = .zero) {
        translatesAutoresizingMaskIntoConstraints = false
        if let superviewLeadingAnchor = superview?.leadingAnchor {
            leadingAnchor.constraint(equalTo: superviewLeadingAnchor, constant: padding.left).isActive = true
        }

        if let superviewTrailingAnchor = superview?.trailingAnchor {
            trailingAnchor.constraint(equalTo: superviewTrailingAnchor, constant: -padding.right).isActive = true
        }

        if let superviewBottomAnchor = superview?.bottomAnchor {
            bottomAnchor.constraint(equalTo: superviewBottomAnchor, constant: -padding.bottom).isActive = true
        }

        if let superviewTopAnchor = superview?.topAnchor {
            topAnchor.constraint(equalTo: superviewTopAnchor, constant: padding.top).isActive = true
        }
    }
Alastar
  • 1,284
  • 1
  • 8
  • 14
0

Use this code snippet in your viewcontroller to shrink the text as it increases.

func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    myTextField.minimumFontSize = 4.0
    myTextField.setNeedsLayout()
    myTextField.layoutIfNeeded()
}
Zeeshan Ahmed
  • 834
  • 8
  • 13
  • Thanks, you're right, that works as intended. That's basically what pooja suggested as well above. I'm also looking for a way to "scroll" to the last character. – j3141592653589793238 Apr 16 '19 at 10:13
  • If there're more than 10 to 15 characters, the font size does not shrink anymore because it is at its lowest value. Further characters get cut off then (as shown on the first image in my question), even if the font size is small. – j3141592653589793238 Apr 16 '19 at 10:23
  • yes defenitely when it will reach the lowest font size, will stop shrinking then it will cut of the characters but then it should show the most recent input characters just like contacts app in iOS, if its behaving like this then its perfect. – Zeeshan Ahmed Apr 16 '19 at 10:26
  • `it should show the most recent input characters` -> Exactly. Unfortunately, that's what it doesn't do. – j3141592653589793238 Apr 16 '19 at 10:26
  • Did you also noticed that in Contacts App the text alignment starts from right side & goes to left might be that also makes difference, kindly check that way as well – Zeeshan Ahmed Apr 16 '19 at 10:32
  • That doesn't make a difference neither. (Btw, just to clarify, I'm talking about the "Phone" app, not "Contacts"). – j3141592653589793238 Apr 16 '19 at 10:36
0

Although I don't like answering my own questions, there seems to be no way around since I've just found a solution.

Alastar was partly correct; instead of using a UITextField, it's way simpler to use a UILabel.

However, the single line that did the trick for me was to set the line break mode to truncate the head:

label.lineBreakMode = .byTruncatingHead

This way,

The line is displayed so that the end fits in the container and the missing text at the beginning of the line is indicated by an ellipsis glyph. Although this mode works for multiline text, it is more often used for single line text.

This is the exact behaviour which Apple used in their "Phone" app (the dial screen).

j3141592653589793238
  • 1,810
  • 2
  • 16
  • 38