iOS 13:UITextField rightView的间距问题

时间:2019-09-30 10:37:16

标签: ios swift uitextfield ios13 xcode11

我在IOS 13中使用UITextField的右视图时遇到间距问题,请参阅下面的代码以及ios 13和ios 12.4的屏幕截图

在IOS 12.4模拟器中,UITextField的右视图(UIButton)中显示适当的空间

在IOS 13.0中,模拟器的UITextField的右视图(UIButton)中存在间距问题

let dropdownButton = UIButton(frame: CGRect(x: 0, y: 0, width: 50, height: txtField.frame.height))
dropdownButton.backgroundColor = UIColor.clear
dropdownButton.setImage(UIImage(named: "ic_DownArrow"), for: UIControl.State())            
txtField.rightView = dropdownButton           
txtField.rightViewMode = .always

enter image description here enter image description here

8 个答案:

答案 0 :(得分:17)

显然,这是rightViewRect(forBounds :)在iOS 13 Beta 5中的行为方式的变化。

摘自iOS&iPadOS 13 Developer Beta 5发行说明:

  

UIKit-已解决的问题

     

在iOS 13之前,UITextField假定在分配时已正确设置其leftView和rightView的帧,并且不会更改。从iOS 13开始,leftViewRect(forBounds :)和rightViewRect(forBounds :)的实现现在向视图询问其systemLayoutSizeFitting(:)。要实现与iOS 13链接并在iOS 13上运行时的先前行为,请在视图上添加显式的大小限制,将其包装在纯UIView中,或者将视图子类化并实现systemLayoutSizeFitting(:)。 (51787798)

因此,将自动布局约束添加到添加到rightView的自定义视图中

示例:-

override func rightViewRect(forBounds bounds: CGRect) -> CGRect {
        return CGRect(x: bounds.width - 30, y: 0, width: 20 , height: bounds.height)
    }

答案 1 :(得分:3)

设置要添加的leftView或rightView的宽度约束。

|   | time_stamp | name | event_1     | event_2     |
|---|------------|------|-------------|-------------|
| 1 | 12345      | foo  | foo_event_1 | foo_event_2 |
| 2 | 12345      | bar  | bar_event_1 | bar_event_2 |

这是我用来设置宽度约束的扩展名:

leftImageView.widthAnchor.set(to: 30.0)
textField.leftView = leftImageView
textField.leftViewMode = .always

答案 2 :(得分:2)

您的图片可能小于width: 50, height: txtField.frame.height,因此按钮变小了。

您可以尝试添加一些容器:

let dropdownButton = UIButton(frame: CGRect(x: 0, y: 0, width: 50, height: txtField.frame.height))
dropdownButton.backgroundColor = .clear
dropdownButton.setImage(UIImage(named: "ic_DownArrow"), for: UIControl.State())
let container = UIView(frame: dropdownButton.frame)
container.backgroundColor = .clear
container.addSubview(dropdownButton)
txtField.rightView = container
txtField.rightViewMode = .always

答案 3 :(得分:2)

我使用Bruno的方法使它工作。

1)创建一个容器视图,并使用自动布局设置其宽度和高度。宽度和高度应包括子视图的大小+所需的间距。

2)创建要在文本字段中显示的子视图。使用自动布局设置宽度,高度和布局。将其添加到容器视图。

3)将容器视图添加到文本字段

您可以看到我的容器与文本字段的高度匹配。宽度是按钮的宽度(44),加上我想要的间距(16)。添加子视图时,将其对齐到容器的左侧。这将使我在按钮的右侧和文本字段的边缘之间有16像素的间距。

let forgotButtonContainer = UIView()
forgotButtonContainer.translatesAutoresizingMaskIntoConstraints = false
forgotButtonContainer.widthAnchor.constraint(equalToConstant: 44.0 + 16.0).isActive = true
forgotButtonContainer.heightAnchor.constraint(equalToConstant: 48.0).isActive = true

forgotButton = PFSecondaryButton(link: "Forgot?")
forgotButton.translatesAutoresizingMaskIntoConstraints = false
forgotButtonContainer.addSubview(forgotButton)

forgotButton.topAnchor.constraint(equalTo: forgotButtonContainer.topAnchor).isActive = true
forgotButton.leftAnchor.constraint(equalTo: forgotButtonContainer.leftAnchor).isActive = true
forgotButton.bottomAnchor.constraint(equalTo: forgotButtonContainer.bottomAnchor).isActive = true

passwordField.rightView = forgotButtonContainer

答案 4 :(得分:0)

我通过设置以下方法解决了相同的问题:

覆盖textField rightViewRectForBounds:方法,

- (CGRect)rightViewRectForBounds:(CGRect)bounds {
    if (self.rightView) {
        CGRect rightFrame = self.rightView.frame;
        return CGRectMake(bounds.size.width - rightFrame.size.width, 0, rightFrame.size.width, bounds.size.height);
    }
    return CGRectZero;
}

答案 5 :(得分:0)

这对我有用,它还解决了iPhone X / 11中发生的问题,当rightView占用了textField的整个宽度时:

txtField.rightView = dropdownButton
txtField.translatesAutoresizingMaskIntoConstraints = false
txtField.rightView?.widthAnchor.constraint(equalToConstant: 50).isActive = true

答案 6 :(得分:0)

为此,我遇到的另一个解决方案是将要分配给iOS 13+的translatesAutoresizingMaskIntoConstraints的视图的true设置为leftView,否则将false的视图设置为<head> ابتداء القول الأول </head> <p> وأيضاً بعض الحيوان البحرى لجى وبعضه شاطئى، وبعضه صخرى. </p>

答案 7 :(得分:0)

您可以从我制作的扩展名中更改右填充和左填充 ...... 您可以使用IBDesignable,也可以不使用

import UIKit

@IBDesignable
extension UITextField {
    
    @IBInspectable var paddingLeftCustom: CGFloat {
        get {
            return leftView!.frame.size.width
        }
        set {
            let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: newValue, height: frame.size.height))
            if leftView == nil {
                leftView = paddingView
                leftViewMode = .always
            }
            
        }
    }

    @IBInspectable var paddingRightCustom: CGFloat {
        get {
            return rightView!.frame.size.width
        }
        set {
            let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: newValue, height: frame.size.height))
            if rightView == nil {
                rightView = paddingView
                rightViewMode = .always
            }
            
        }
    }
}