如何滚动到 UITextField 中的最后一个字符?
How to scroll to last character in UITextField?
我尝试从 Apple 的 "Phone" 应用重建 UITextField
。
我构建了一个小键盘,其中每个按钮触发特定值(0-9、#、*)并将其附加到文本字段的文本。
textAlignment
属性 设置为 center
。但是,在插入数字时,文本字段不会滚动或移动到最后一个字符。
F.ex.,如果有超过 10 个数字,而我正在添加第 11 个数字,则不会显示第 11 个数字,因为它不在屏幕上。
Apple 通过先缩小字体大小然后滚动到光标位置来处理此问题。
有没有简单的技巧可以达到同样的效果?
我附上了两张图片。
使用这个例子。设置光标并滚动到 UITextField
的末尾。因为你用 UI 进行操作,所以你必须在主线程中进行
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)
}
您需要在 Storyboard 中设置文本视图的最小字体大小,并选中其下方的调整以适合复选框。
为什么使用文本字段而不是 uilabel?
这可以通过
轻松解决
label.adjustsFontSizeToFitWidth = true
label.textAlignment = .center
label.setFillSuperview(withPadding: UIEdgeInsets(top: 0, left: whatYouNeed, bottom: 0, right: whatYouNeed))
并向 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
}
}
在您的 viewcontroller 中使用此代码段可在文本增加时缩小文本。
func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
myTextField.minimumFontSize = 4.0
myTextField.setNeedsLayout()
myTextField.layoutIfNeeded()
}
虽然我不喜欢回答自己的问题,但似乎没有办法,因为我刚刚找到了解决方案。
Alastar 部分正确;与其使用 UITextField
,不如使用 UILabel
更简单。
然而,对我有用的唯一一行是将换行模式设置为截断头部:
label.lineBreakMode = .byTruncatingHead
这样,
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.
这正是 Apple 在他们的 "Phone" 应用程序(拨号屏幕)中使用的行为。
我尝试从 Apple 的 "Phone" 应用重建 UITextField
。
我构建了一个小键盘,其中每个按钮触发特定值(0-9、#、*)并将其附加到文本字段的文本。
textAlignment
属性 设置为 center
。但是,在插入数字时,文本字段不会滚动或移动到最后一个字符。
F.ex.,如果有超过 10 个数字,而我正在添加第 11 个数字,则不会显示第 11 个数字,因为它不在屏幕上。
Apple 通过先缩小字体大小然后滚动到光标位置来处理此问题。
有没有简单的技巧可以达到同样的效果?
我附上了两张图片。
使用这个例子。设置光标并滚动到 UITextField
的末尾。因为你用 UI 进行操作,所以你必须在主线程中进行
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)
}
您需要在 Storyboard 中设置文本视图的最小字体大小,并选中其下方的调整以适合复选框。
为什么使用文本字段而不是 uilabel?
这可以通过
轻松解决label.adjustsFontSizeToFitWidth = true
label.textAlignment = .center
label.setFillSuperview(withPadding: UIEdgeInsets(top: 0, left: whatYouNeed, bottom: 0, right: whatYouNeed))
并向 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
}
}
在您的 viewcontroller 中使用此代码段可在文本增加时缩小文本。
func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
myTextField.minimumFontSize = 4.0
myTextField.setNeedsLayout()
myTextField.layoutIfNeeded()
}
虽然我不喜欢回答自己的问题,但似乎没有办法,因为我刚刚找到了解决方案。
Alastar 部分正确;与其使用 UITextField
,不如使用 UILabel
更简单。
然而,对我有用的唯一一行是将换行模式设置为截断头部:
label.lineBreakMode = .byTruncatingHead
这样,
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.
这正是 Apple 在他们的 "Phone" 应用程序(拨号屏幕)中使用的行为。