#swift #uitextfield #textfield #text-alignment
#swift #uitextfield #текстовое поле #выравнивание текста
Вопрос:
Я хочу создать пользовательское текстовое поле с левым правым нижним верхним заполнением. Поэтому я использую приведенный ниже код для достижения этого:
class CustomTextField: UITextField {
let padding = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8);
override func textRect(forBounds bounds: CGRect) -> CGRect {
return bounds.inset(by: padding)
}
override func placeholderRect(forBounds bounds: CGRect) -> CGRect {
return bounds.inset(by: padding)
}
override func editingRect(forBounds bounds: CGRect) -> CGRect {
return bounds.inset(by: padding)
} }
Я также хочу, чтобы выравнивание текста-заполнителя было сверху, а не по центру TF. Я использую приведенный ниже код:
textField.contentVerticalAlignment = .top
Однако, когда я попытался установить вертикальное выравнивание с помощью отступов, выравнивание не сработало. Только тогда, когда я удалю отступы, это будет работать. Я имел в виду, что это будет работать только с любым из них. Как я могу добиться их обоих? Кроме того, возможно ли отображать многострочный текст-заполнитель вместо отображения его в одной строке с точками в конце?
Ответ №1:
Вам нужно переопределить placeholderRect(forBounds:)
, вот так
override func placeholderRect(forBounds bounds: CGRect) -> CGRect {
var placeholderPadding = self.padding
placeholderPadding.top = 0
var rect = bounds.inset(by: placeholderPadding)
// We need to adjust placeholder in-case there is a leftView or rightView
if rightViewMode == .always || rightViewMode == .unlessEditing, let rightViewWidth = self.rightView?.frame.width {
rect.size.width -= rightViewWidth
}
if leftViewMode == .always || leftViewMode == .unlessEditing, let leftViewWidth = self.leftView?.frame.width {
rect.size.width -= leftViewWidth
}
return rect
}
Вопрос-2: UITextField
работает только на 1 строке, для этого вам нужно взглянуть на UITextView
Комментарии:
1. могу ли я узнать, какое условие для if { … } для режима просмотра справа и режима просмотра слева? потому что он показывает ошибку, когда для этого нет условия
2. опечатка, я избавился от этого
3. не работает, все так же, как на скриншоте, который я показываю выше. кстати, спасибо за ваш ответ. Я думаю, мне нужно изменить его на текстовый вид, так как мне нужно более 1 строки текста.
Ответ №2:
для первого вопроса вы можете расширить UIView общедоступным расширением UIView {
/// SwifterSwift: Border color of view; also inspectable from Storyboard.
@IBInspectable public var borderColor: UIColor? {
get {
guard let color = layer.borderColor else { return nil }
return UIColor(cgColor: color)
}
set {
guard let color = newValue else {
layer.borderColor = nil
return
}
// Fix React-Native conflict issue
guard String(describing: type(of: color)) != "__NSCFType" else { return }
layer.borderColor = color.cgColor
}
}
/// SwifterSwift: Border width of view; also inspectable from Storyboard.
@IBInspectable public var borderWidth: CGFloat {
get {
return layer.borderWidth
}
set {
layer.borderWidth = newValue
}
}
/// SwifterSwift: Corner radius of view; also inspectable from Storyboard.
@IBInspectable public var cornerRadius: CGFloat {
get {
return layer.cornerRadius
}
set {
layer.masksToBounds = true
layer.cornerRadius = abs(CGFloat(Int(newValue * 100)) / 100)
}
}
/// SwifterSwift: Height of view.
public var height: CGFloat {
get {
return frame.size.height
}
set {
frame.size.height = newValue
}
}
/// SwifterSwift: Check if view is in RTL format.
public var isRightToLeft: Bool {
if #available(iOS 10.0, *, tvOS 10.0, *) {
return effectiveUserInterfaceLayoutDirection == .rightToLeft
} else {
return false
}
}
/// SwifterSwift: Take screenshot of view (if applicable).
public var screenshot: UIImage? {
UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, 0)
defer {
UIGraphicsEndImageContext()
}
guard let context = UIGraphicsGetCurrentContext() else { return nil }
layer.render(in: context)
return UIGraphicsGetImageFromCurrentImageContext()
}
/// SwifterSwift: Shadow color of view; also inspectable from Storyboard.
@IBInspectable public var shadowColor: UIColor? {
get {
guard let color = layer.shadowColor else { return nil }
return UIColor(cgColor: color)
}
set {
layer.shadowColor = newValue?.cgColor
}
}
/// SwifterSwift: Shadow offset of view; also inspectable from Storyboard.
@IBInspectable public var shadowOffset: CGSize {
get {
return layer.shadowOffset
}
set {
layer.shadowOffset = newValue
}
}
/// SwifterSwift: Shadow opacity of view; also inspectable from Storyboard.
@IBInspectable public var shadowOpacity: Float {
get {
return layer.shadowOpacity
}
set {
layer.shadowOpacity = newValue
}
}
/// SwifterSwift: Shadow radius of view; also inspectable from Storyboard.
@IBInspectable public var shadowRadius: CGFloat {
get {
return layer.shadowRadius
}
set {
layer.shadowRadius = newValue
}
}
/// SwifterSwift: Size of view.
public var size: CGSize {
get {
return frame.size
}
set {
width = newValue.width
height = newValue.height
}
}
/// SwifterSwift: Get view's parent view controller
public var parentViewController: UIViewController? {
weak var parentResponder: UIResponder? = self
while parentResponder != nil {
parentResponder = parentResponder!.next
if let viewController = parentResponder as? UIViewController {
return viewController
}
}
return nil
}
/// SwifterSwift: Width of view.
public var width: CGFloat {
get {
return frame.size.width
}
set {
frame.size.width = newValue
}
}
// swiftlint:disable next identifier_name
/// SwifterSwift: x origin of view.
public var x: CGFloat {
get {
return frame.origin.x
}
set {
frame.origin.x = newValue
}
}
// swiftlint:disable next identifier_name
/// SwifterSwift: y origin of view.
public var y: CGFloat {
get {
return frame.origin.y
}
set {
frame.origin.y = newValue
}
}}
это предоставит вам эти функции в инспекторе атрибутов
что касается второго вопроса, UITextField состоит всего из одной строки, поэтому попробуйте использовать UITextView