ios 添加底线以在 SwiftUI/Swift/Objective-C/Xamarin 中查看

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26800963/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 03:32:37  来源:igfitidea点击:

Add bottom line to view in SwiftUI / Swift / Objective-C / Xamarin

iosobjective-cswiftxamarinswiftui

提问by dhaval shah

I would like to keep the border at the bottom part only in UITextField. But I don't know how we can keep it on the bottom side.

我只想将底部的边框保留在UITextField. 但我不知道我们如何将它保持在底部。

Can you please advise me?

你能给我建议吗?

回答by Kampai

I am creating custom textFieldto make it reusable component for SwiftUI

我正在创建自定义textField以使其成为 SwiftUI 的可重用组件

SwiftUI

用户界面

struct CustomTextField: View {
    var placeHolder: String
    @Binding var value: String

    var lineColor: Color
    var width: CGFloat

    var body: some View {
        VStack {
            TextField(self.placeHolder, text: $value)
            .padding()
            .font(.title)

            Rectangle().frame(height: self.width)
                .padding(.horizontal, 20).foregroundColor(self.lineColor)
        }
    }
}

Usage:

用法:

@Binding var userName: String
@Binding var password: String

var body: some View {
    VStack(alignment: .center) {
        CustomTextField(placeHolder: "Username", value: $userName, lineColor: .white, width: 2)
        CustomTextField(placeHolder: "Password", value: $password, lineColor: .white, width: 2)
    }
}




Swift 5.0

斯威夫特 5.0

I am using Visual Formatting Language (VFL) here, This will allow adding a line to any UIControl.

我在这里使用可视化格式语言 (VFL),这将允许向任何UIControl.

You can create a UIViewextension class like UIView+Extention.swift

您可以创建一个UIView扩展类,如UIView+Extention.swift

import UIKit

enum LINE_POSITION {
    case LINE_POSITION_TOP
    case LINE_POSITION_BOTTOM
}

extension UIView {
    func addLine(position : LINE_POSITION, color: UIColor, width: Double) {
        let lineView = UIView()
        lineView.backgroundColor = color
        lineView.translatesAutoresizingMaskIntoConstraints = false // This is important!
        self.addSubview(lineView)

        let metrics = ["width" : NSNumber(value: width)]
        let views = ["lineView" : lineView]
        self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[lineView]|", options:NSLayoutConstraint.FormatOptions(rawValue: 0), metrics:metrics, views:views))

        switch position {
        case .LINE_POSITION_TOP:
            self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[lineView(width)]", options:NSLayoutConstraint.FormatOptions(rawValue: 0), metrics:metrics, views:views))
            break
        case .LINE_POSITION_BOTTOM:
            self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[lineView(width)]|", options:NSLayoutConstraint.FormatOptions(rawValue: 0), metrics:metrics, views:views))
            break
        }
    }
}

Usage:

用法:

textField.addLine(position: .LINE_POSITION_BOTTOM, color: .darkGray, width: 0.5)


Objective C:

目标 C:

You can add this helper method to your global helper class(I used global class method) or in the same view controller(using an instance method).

您可以将此辅助方法添加到全局辅助类(我使用全局类方法)或同一个视图控制器中(使用实例方法)。

typedef enum : NSUInteger {
    LINE_POSITION_TOP,
    LINE_POSITION_BOTTOM
} LINE_POSITION;


- (void) addLine:(UIView *)view atPosition:(LINE_POSITION)position withColor:(UIColor *)color lineWitdh:(CGFloat)width {
    // Add line
    UIView *lineView = [[UIView alloc] init];
    [lineView setBackgroundColor:color];
    [lineView setTranslatesAutoresizingMaskIntoConstraints:NO];
    [view addSubview:lineView];

    NSDictionary *metrics = @{@"width" : [NSNumber numberWithFloat:width]};
    NSDictionary *views = @{@"lineView" : lineView};
    [view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[lineView]|" options: 0 metrics:metrics views:views]];

    switch (position) {
        case LINE_POSITION_TOP:
            [view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[lineView(width)]" options: 0 metrics:metrics views:views]];
            break;

        case LINE_POSITION_BOTTOM:
            [view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[lineView(width)]|" options: 0 metrics:metrics views:views]];
            break;
        default: break;
    }
}

Usage:

用法:

[self addLine:self.textField atPosition:LINE_POSITION_TOP withColor:[UIColor darkGrayColor] lineWitdh:0.5];


Xamarin code:

Xamarin 代码:

 var border = new CALayer();
 nfloat width = 2;
 border.BorderColor = UIColor.Black.CGColor;
 border.Frame = new CoreGraphics.CGRect(0, textField.Frame.Size.Height - width, textField.Frame.Size.Width, textField.Frame.Size.Height);
 border.BorderWidth = width;
 textField.Layer.AddSublayer(border);
 textField.Layer.MasksToBounds = true;

回答by sasquatch

If you want to do without knowing framesbeforehand, without subclassingand without Autolayout:

如果你想在不知道框架的情况下做,没有子类化Autolayout

Swift 5/ Swift 4.x/ Swift 3.x

斯威夫特 5/ 斯威夫特 4.x/ 斯威夫特 3.x

extension UITextField {
  func setBottomBorder() {
    self.borderStyle = .none
    self.layer.backgroundColor = UIColor.white.cgColor

    self.layer.masksToBounds = false
    self.layer.shadowColor = UIColor.gray.cgColor
    self.layer.shadowOffset = CGSize(width: 0.0, height: 1.0)
    self.layer.shadowOpacity = 1.0
    self.layer.shadowRadius = 0.0
  }
}

Call as yourTextField.setBottomBorder()from anywhere without making sure of the frames to be right.

yourTextField.setBottomBorder()在不确保帧正确的情况下从任何地方调用。

The Result looks like this:

结果如下所示:

sample

样本

回答by user1046037

You can create a subclass of UITextFieldas shown below:

您可以创建UITextField如下所示的子类:

class TextField : UITextField {

    override var tintColor: UIColor! {

        didSet {
            setNeedsDisplay()
        }
    }

    override func draw(_ rect: CGRect) {

        let startingPoint   = CGPoint(x: rect.minX, y: rect.maxY)
        let endingPoint     = CGPoint(x: rect.maxX, y: rect.maxY)

        let path = UIBezierPath()

        path.move(to: startingPoint)
        path.addLine(to: endingPoint)
        path.lineWidth = 2.0

        tintColor.setStroke()

        path.stroke()
    }
}

回答by inf1783

None of these solutions really met my expectations. I wanted to subclassthe TextField since I don't want to set the border manually all the time. I also wanted to change the border colore.g. for an error. So here's my solution with Anchors:

这些解决方案都没有真正满足我的期望。我想对TextField进行子类化,因为我不想一直手动设置边框。我还想更改边框颜色,例如错误。所以这是我的解决方案Anchors

class CustomTextField: UITextField {

    var bottomBorder = UIView()

    override func awakeFromNib() {

            // Setup Bottom-Border

            self.translatesAutoresizingMaskIntoConstraints = false

            bottomBorder = UIView.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
            bottomBorder.backgroundColor = UIColor(rgb: 0xE2DCD1) // Set Border-Color
            bottomBorder.translatesAutoresizingMaskIntoConstraints = false

            addSubview(bottomBorder)

            bottomBorder.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
            bottomBorder.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
            bottomBorder.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
            bottomBorder.heightAnchor.constraint(equalToConstant: 1).isActive = true // Set Border-Strength

    }
}

---- Optional ----

- - 可选的 - -

To change the color add sth like this to the CustomTextField Class:

要更改颜色,请在以下内容中添加以下内容CustomTextField Class

@IBInspectable var hasError: Bool = false {
    didSet {

        if (hasError) {

            bottomBorder.backgroundColor = UIColor.red

        } else {

            bottomBorder.backgroundColor = UIColor(rgb: 0xE2DCD1)

        }

    }
}

And to trigger the Error call this after you created an instance of CustomTextField

并在创建 CustomTextField 实例后触发错误调用

textField.hasError = !textField.hasError

enter image description here

在此处输入图片说明

Hope it helps someone ;)

希望它可以帮助某人;)

回答by idris y?ld?z

 extension UITextField {  
  func setBottomBorder(color:String) {
    self.borderStyle = UITextBorderStyle.None
    let border = CALayer()
    let width = CGFloat(1.0)
    border.borderColor = UIColor(hexString: color)!.cgColor
    border.frame = CGRect(x: 0, y: self.frame.size.height - width,   width:  self.frame.size.width, height: self.frame.size.height)
    border.borderWidth = width
    self.layer.addSublayer(border)
    self.layer.masksToBounds = true
   }
}

and then just do this:

然后就这样做:

yourTextField.setBottomBorder(color: "#3EFE46")

回答by Rishabh Wadhwa

You can create this extension outside class and replace width with whatever borderWidth you want.

您可以在类之外创建此扩展并将宽度替换为您想要的任何边框宽度。

Swift 4

斯威夫特 4

extension UITextField
{
    func setBottomBorder(withColor color: UIColor)
    {
        self.borderStyle = UITextBorderStyle.none
        self.backgroundColor = UIColor.clear
        let width: CGFloat = 1.0

        let borderLine = UIView(frame: CGRect(x: 0, y: self.frame.height - width, width: self.frame.width, height: width))
        borderLine.backgroundColor = color
        self.addSubview(borderLine)
    }
}

Original

原来的

extension UITextField
{
    func setBottomBorder(borderColor: UIColor)
    {
        self.borderStyle = UITextBorderStyle.None
        self.backgroundColor = UIColor.clearColor()
        let width = 1.0

        let borderLine = UIView(frame: CGRectMake(0, self.frame.height - width, self.frame.width, width))
        borderLine.backgroundColor = borderColor
        self.addSubview(borderLine)
    }
}

and then add this to your viewDidLoad replacing yourTextField with your UITextField variable and with any color you want in the border

然后将此添加到您的 viewDidLoad 用您的 UITextField 变量和您想要的边框颜色替换 yourTextField

yourTextField.setBottomBorder(UIColor.blackColor())

This basically adds a view with that color at the bottom of the text field.

这基本上在文本字段的底部添加了具有该颜色的视图。

回答by Mitul Marsoniya

enter image description here

在此处输入图片说明

Objective C

目标 C

        [txt.layer setBackgroundColor: [[UIColor whiteColor] CGColor]];
        [txt.layer setBorderColor: [[UIColor grayColor] CGColor]];
        [txt.layer setBorderWidth: 0.0];
        [txt.layer setCornerRadius:12.0f];
        [txt.layer setMasksToBounds:NO];
        [txt.layer setShadowRadius:2.0f];
        txt.layer.shadowColor = [[UIColor blackColor] CGColor];
        txt.layer.shadowOffset = CGSizeMake(1.0f, 1.0f);
        txt.layer.shadowOpacity = 1.0f;
        txt.layer.shadowRadius = 1.0f;

Swift

迅速

        txt.layer.backgroundColor = UIColor.white.cgColor
        txt.layer.borderColor = UIColor.gray.cgColor
        txt.layer.borderWidth = 0.0
        txt.layer.cornerRadius = 5
        txt.layer.masksToBounds = false
        txt.layer.shadowRadius = 2.0
        txt.layer.shadowColor = UIColor.black.cgColor
        txt.layer.shadowOffset = CGSize.init(width: 1.0, height: 1.0)
        txt.layer.shadowOpacity = 1.0
        txt.layer.shadowRadius = 1.0

回答by Krishna Vedula

What I did was to create an extension to UITextField and added a Designer editable property. Setting this property to any color would change the border (bottom) to that color (setting other borders to none).

我所做的是为 UITextField 创建一个扩展并添加一个 Designer 可编辑属性。将此属性设置为任何颜色会将边框(底部)更改为该颜色(将其他边框设置为无)。

Since this also requires to change the place holder text color, I also added that to the extension.

由于这也需要更改占位符文本颜色,因此我还将其添加到扩展名中。

    extension UITextField {

    @IBInspectable var placeHolderColor: UIColor? {
        get {
            return self.placeHolderColor
        }
        set {
            self.attributedPlaceholder = NSAttributedString(string:self.placeholder != nil ? self.placeholder! : "", attributes:[NSForegroundColorAttributeName: newValue!])
        }
    }


    @IBInspectable var bottomBorderColor: UIColor? {
        get {
            return self.bottomBorderColor
        }
        set {
            self.borderStyle = UITextBorderStyle.None;
            let border = CALayer()
            let width = CGFloat(0.5)
            border.borderColor = newValue?.CGColor
            border.frame = CGRect(x: 0, y: self.frame.size.height - width,   width:  self.frame.size.width, height: self.frame.size.height)

            border.borderWidth = width
            self.layer.addSublayer(border)
            self.layer.masksToBounds = true

        }
    }
}

回答by afrodev

On Swift 3. You can create an extension and add after your view class.

在 Swift 3 上。您可以创建一个扩展并添加到您的视图类之后。

extension UITextField
{
    func setBottomBorder(borderColor: UIColor)
    {

        self.borderStyle = UITextBorderStyle.none
        self.backgroundColor = UIColor.clear
        let width = 1.0

        let borderLine = UIView()
        borderLine.frame = CGRect(x: 0, y: Double(self.frame.height) - width, width: Double(self.frame.width), height: width)

        borderLine.backgroundColor = borderColor
        self.addSubview(borderLine)
    }
}

回答by iman

Please have a look at the below code sample;

请看下面的代码示例;

Swift 4:

斯威夫特 4:

@IBDesignable class DesignableUITextField: UITextField {

    let border = CALayer()

    @IBInspectable var borderColor: UIColor? {
        didSet {
            setup()
        }
    }

    @IBInspectable var borderWidth: CGFloat = 0.5 {
        didSet {
            setup()
        }
    }

    func setup() {
        border.borderColor = self.borderColor?.cgColor

        border.borderWidth = borderWidth
        self.layer.addSublayer(border)
        self.layer.masksToBounds = true
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        border.frame = CGRect(x: 0, y: self.frame.size.height - borderWidth, width:  self.frame.size.width, height: self.frame.size.height)
    }
 }