【问题标题】:iOS - Best Approach to Design Custom UITextField with Transparent BackgroundiOS - 设计具有透明背景的自定义 UITextField 的最佳方法
【发布时间】:2018-11-29 13:46:20
【问题描述】:

我必须创建上图中给出的文本字段。此文本字段将在UITableViewCellUIView 内的整个应用程序中使用。什么可能是最好的方法?

到目前为止,我认为UIBezierPath 是最后一个选择。

【问题讨论】:

  • 如果您的设计师可以为您提供带边框的透明图像,您可以使用该图像设置文本字段的背景属性。
  • 画出使用代码应该没有那么难,我想你已经厌倦了,因为你以前没有做过?但是,如果您对可用的绘图工具进行一些阅读,我想您会发现它非常简单
  • @LoVo 我认为他需要一个透明的文本字段而不是为其设置背景图像
  • 我已经对各种视图的透明图像和边框做出了很好的体验,只要设计师知道他在做什么,它就会产生相同的效果,但编程工作量要少得多。跨度>
  • 到目前为止你尝试过什么代码?

标签: ios swift uitextfield core-graphics uibezierpath


【解决方案1】:

非常有趣的问题,我真的很喜欢那个 UITextField 的设计,所以我在一个类中实现了它。我已经完成了所有@IBDesignable 和@IBInspectable

代码如下:

//
//  AMTitledTextField.swift
//
//  Created with ? by Alessandro Manilii on 29/11/2018.
//  Copyright © 2018 Alessandro Manilii. All rights reserved.
//

import UIKit

@IBDesignable
class AMTitledTextField: UITextField {

    // MARK: - IBInspectables
    @IBInspectable var title: String = "" {
        didSet { self.updateTextViewBorder() }
    }

    @IBInspectable var titleColor: UIColor = UIColor.black {
        didSet { updateTextViewBorder() }
    }

    @IBInspectable var borderWidth: CGFloat = 0.0 {
        didSet { updateTextViewBorder() }
    }

    @IBInspectable var borderColor: UIColor = UIColor.clear {
        didSet { updateTextViewBorder() }
    }

    @IBInspectable var cornerRadius: CGFloat = 0.0 {
        didSet { updateTextViewBorder() }
    }

    @IBInspectable var placeholderColor: UIColor = .lightGray {
        didSet { setValue(placeholderColor, forKeyPath: "_placeholderLabel.textColor") }
    }

    // MARK: - Properties
    private var borderLayer: CAShapeLayer?
    private var sidePadding: CGFloat = 8.0
    private let verticalPadding: CGFloat = 12.0
    private var lblTitle: UILabel?

    var originNew: CGPoint {
        get { return CGPoint(x: cornerRadius + borderWidth/2, y: 0) }
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        updateTextViewBorder()
    }
}

extension AMTitledTextField {

    func updateTextViewBorder() {
        borderStyle = .none
        createTitle()
        borderLayer?.removeFromSuperlayer()
        borderLayer = nil
        borderLayer = CAShapeLayer()
        guard let borderLayer = borderLayer else { return }
        borderLayer.path = createPath().cgPath
        borderLayer.strokeColor = borderColor.cgColor
        borderLayer.fillColor = UIColor.clear.cgColor
        borderLayer.lineWidth = borderWidth
        self.layer.addSublayer(borderLayer)
    }
}

// MARK: - Rectangles Setup
extension AMTitledTextField {

    var fullSidePadding : CGFloat { return cornerRadius + sidePadding }
    var topPadding      : CGFloat { return verticalPadding/2 }
    var textPadding     : CGFloat {return sidePadding/2}

    override public func textRect(forBounds bounds: CGRect) -> CGRect {
        return bounds.inset(by: UIEdgeInsets.init(top: topPadding,
                                                  left: fullSidePadding + textPadding,
                                                  bottom: 0,
                                                  right: fullSidePadding))
    }

    override public func editingRect(forBounds bounds: CGRect) -> CGRect {
        return bounds.inset(by: UIEdgeInsets.init(top: topPadding,
                                                  left: fullSidePadding + textPadding,
                                                  bottom: 0,
                                                  right: fullSidePadding))
    }

    override public func placeholderRect(forBounds bounds: CGRect) -> CGRect {
        return bounds.inset(by: UIEdgeInsets.init(top: topPadding,
                                                  left: fullSidePadding + textPadding,
                                                  bottom: 0,
                                                  right: fullSidePadding))
    }

    override public func borderRect(forBounds bounds: CGRect) -> CGRect {
        return bounds.inset(by: UIEdgeInsets.init(top: 0,
                                                  left: fullSidePadding + textPadding,
                                                  bottom: 0,
                                                  right: fullSidePadding))
    }
}

private extension AMTitledTextField {

    func setPlaceholderColor(_ color: UIColor) {
        var placeholderText = ""
        if let placeholder = self.placeholder {
            placeholderText = placeholder
        }

        self.attributedPlaceholder = NSAttributedString(string: placeholderText, attributes: [NSAttributedString.Key.foregroundColor: color])
    }

    func createTitle() {
        lblTitle = nil
        lblTitle = UILabel(frame: CGRect(x: originNew.x, y: originNew.y, width: 25, height: 25))
        guard let lblTitle = lblTitle else { return }

        lblTitle.textAlignment = .center
        lblTitle.text = title
        lblTitle.textColor = titleColor
        lblTitle.font = font
        if let fontSize = font?.pointSize {
            lblTitle.font = lblTitle.font.withSize(fontSize * 0.85)
        }

        lblTitle.sizeToFit()
        lblTitle.frame = CGRect(x: lblTitle.frame.origin.x + sidePadding, y: lblTitle.frame.origin.y, width: lblTitle.frame.width + sidePadding, height: lblTitle.frame.height);
        addSubview(lblTitle)
    }

    func createPath() -> UIBezierPath  {
        let path = UIBezierPath()
        guard let lblTitle = lblTitle else { return path }

        let pointA = CGPoint(x: originNew.x + lblTitle.frame.width + sidePadding, y: lblTitle.center.y)
        let pointB = CGPoint(x: frame.width - cornerRadius - borderWidth/2, y: pointA.y)
        let centerUR = CGPoint(x: pointB.x, y: pointA.y + cornerRadius)
        let pointC = CGPoint(x: frame.width - borderWidth/2, y: frame.height - cornerRadius - borderWidth/2)
        let centerBR = CGPoint(x: centerUR.x, y: frame.height - cornerRadius - borderWidth/2)
        let pointD = CGPoint(x: cornerRadius + borderWidth/2, y: frame.height - borderWidth/2)
        let centerBL = CGPoint(x: pointD.x, y: centerBR.y)
        let pointE = CGPoint(x: borderWidth/2, y: centerUR.y)
        let centerUL = CGPoint(x: centerBL.x, y: centerUR.y)
        let pointF = CGPoint(x: pointD.x + sidePadding, y: pointA.y)

        path.move(to: pointA)
        path.addLine(to: pointB)
        path.addArc(withCenter: centerUR, radius: cornerRadius, startAngle: CGFloat(3 * Double.pi/2), endAngle: 0, clockwise: true)
        path.addLine(to: pointC)
        path.addArc(withCenter: centerBR, radius: cornerRadius, startAngle: 0, endAngle: CGFloat(Double.pi/2), clockwise: true)
        path.addLine(to: pointD)
        path.addArc(withCenter: centerBL, radius: cornerRadius, startAngle: CGFloat(Double.pi/2), endAngle: CGFloat(2 * Double.pi/2), clockwise: true)
        path.addLine(to: pointE)
        path.addArc(withCenter: centerUL, radius: cornerRadius, startAngle:  CGFloat(2 * Double.pi/2), endAngle:  CGFloat(3 * Double.pi/2), clockwise: true)
        path.addLine(to: pointF)

        return path
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多