在保持缩进的同时难以移除UITextView边框

时间:2019-04-30 20:53:01

标签: uitextfield border padding drag

我正在编写一个iOS应用,用户可以在其中添加文本字段,然后将其拖动到屏幕上以重新定位它们,布局风格类似于Keynote。

我目前正在将用户添加的UITextFields附加到@IBOutlet集合,并且默认为.borderStyle = .roundedRect,以使所选文本周围出现模糊的边框,指示该字段已选中。调用textFieldDidBeginEditing时,任何UITextField都将设置为.roundedRect边框样式,调用textFieldDidEndEditing时,将切换为textField.borderStyle = .none。

所有人似乎都解决了一个问题:将边框样式切换为.none时,文本字段会丢失边框周围的缩进,将文本向外移并将其放置在用户无意的位置(图形会添加一个背景色为红色,只是为了显示偏移,但是最终我将允许用户设置背景色,因此仅对UITextField进行偏移是不可行的)。

enter image description here

我也尝试在以下位置调整答案: Create space at the beginning of a UITextField 为TextView设置.roundedRect时设置无填充插图,但在.borderStyle为.none时添加填充。这似乎没有效果。

其他答案已建议设置 textField.layer.borderColor = UIColor.clear.cgColor 要么 textField.layer.borderWidth = 0.0

但这些似乎都没有作用

我最终将允许用户更改每个TextField的字体和大小,因此无论是否选择UITextField,以及字体选择如何,我都希望任何缩进都保持一致。

代码在下面。如果我缺少更好的解决方案,则欢迎提出建议,也为我设定了新的方法。

谢谢! 约翰

class ViewController: UIViewController, UITextFieldDelegate {
    @IBOutlet weak var screenView: UIView! // a 320 x 240 view
    @IBOutlet var fieldCollection: [UITextField]! // Not connected, fields created programmatically

    // below are used in .inset(by:) but seems to have no effect
    let padding = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
    let noPadding = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)

    override func viewDidLoad() {
        super.viewDidLoad()
        // hide keyboard if we tap outside of a field
        let tap = UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:)))
        tap.cancelsTouchesInView = false
        self.view.addGestureRecognizer(tap)
        createNewField()
    }

    // Select / deselect text fields
    func textFieldDidBeginEditing(_ textField: UITextField) {
        textField.borderStyle = .roundedRect
        // textField.bounds.inset(by: noPadding) // effect is the same if left out
    }

    func textFieldDidEndEditing(_ textField: UITextField) {
        textField.borderStyle = .none
        // textField.bounds.inset(by: padding) // effect is the same if left out
    }

    // UITextField created & added to fieldCollection
    func createNewField() {
        let newFieldRect = CGRect(x: 0, y: 0, width: 320, height: 30)
        let newField = UITextField(frame: newFieldRect)
        newField.borderStyle = .roundedRect
        newField.isUserInteractionEnabled = true
        newField.addGestureRecognizer(addGestureToField())
        screenView.addSubview(newField)
        if fieldCollection == nil {
            fieldCollection = [newField]
        } else {
            fieldCollection.append(newField)
        }
        newField.delegate = self
        newField.becomeFirstResponder()
    }

    func addGestureToField() -> UIPanGestureRecognizer {
        var panGesture = UIPanGestureRecognizer()
        panGesture = UIPanGestureRecognizer(target: self, action: #selector(draggedView(_:)))
        return panGesture
    }

    // event handler when a field(view) is dragged
    @objc func draggedView(_ sender:UIPanGestureRecognizer){
        sender.view!.becomeFirstResponder()
        let selectedView = sender.view as! UITextField
        selectedView.bringSubviewToFront(selectedView)
        let translation = sender.translation(in: screenView)
        selectedView.center = CGPoint(x: selectedView.center.x + translation.x, y: selectedView.center.y + translation.y)
        sender.setTranslation(CGPoint.zero, in: screenView)
    }

    @IBAction func addFieldPressed(_ sender: UIButton) {
        createNewField()
    }
}

1 个答案:

答案 0 :(得分:0)

我可以通过将UITextField子类化来解决此问题:

class PaddedTextField: UITextField {
    let padding = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8)
    let noPadding = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)

    override open func textRect(forBounds bounds: CGRect) -> CGRect {
        if self.borderStyle == .none {
            let content = bounds.inset(by: padding)
            return content
        } else {
            return bounds.inset(by: noPadding)
        }
    }
}

然后我将newField对象的创建从使用UITextField更改为: 让newField = PaddedTextField(frame:newFieldRect)

还有一个变化。需要更适当地计算高度。由于我所有的文本字段都可以从包围的超级视图的整个长度开始(320点),因此我修改了原始的newFieldRect,使用.sizeToFit()创建具有适当高度的文本框。其他尺寸将不正确b / c我在文本视图中没有任何内容,但是我提取了.height并将其与原始初始化参数一起使用。

newField.sizeToFit()
let newFieldHeight = newField.frame.height
newFieldRect = CGRect(x: 0, y: 0, width: 320, height: newFieldHeight)
newField.frame = newFieldRect

在此希望它可以帮助您节省时间。