[ios] SwiftUI / Swift / Objective-C / Xamarin에서 볼 수있는 결론 추가

의 하단 부분에만 테두리를 유지하고 싶습니다 UITextField. 그러나 우리가 어떻게 그것을 바닥에 유지할 수 있는지 모르겠습니다.

저에게 조언 해주시겠습니까?



답변

textFieldSwiftUI의 재사용 가능한 구성 요소로 만들기 위해 사용자 정의 를 작성하고 있습니다.

스위프트 UI

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)
        }
    }
}

용법:

@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)
    }
}


스위프트 5.0

여기서 VFL (Visual Formatting Language)을 사용하고 있습니다. 그러면 any에 행을 추가 할 수 UIControl있습니다.

다음 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
        }
    }
}

용법:

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

목표 C :

이 도우미 메서드를 전역 도우미 클래스 (글로벌 클래스 메서드 사용) 또는 동일한 뷰 컨트롤러 (인스턴스 메서드 사용)에 추가 할 수 있습니다.

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;
    }
}

용법:

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

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;


답변

사전에 프레임을 알지 않고 서브 클래스 를 사용 하지 않고 자동 레이아웃 을 수행 하지 않으려면 다음을 수행 하십시오 .

스위프트 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
  }
}

yourTextField.setBottomBorder()프레임이 올바른지 확인하지 않고 어디서나 전화 를 걸 수 있습니다.

결과는 다음과 같습니다.

견본

스위프트 UI

struct MyTextField: View {
  var myPlaceHolder: String
  @Binding var text: String

  var underColor: Color
  var height: CGFloat

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

        Rectangle().frame(height: self.height)
            .padding(.horizontal, 24).foregroundColor(self.underColor)
    }
  }
}


답변

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()
    }
}


답변

이 솔루션들 중 어느 것도 실제로 나의 기대를 충족시키지 못했습니다. 테두리를 항상 수동으로 설정하고 싶지 않기 때문에 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

    }
}

—- 옵션 —-

색상을 변경하려면 다음과 같이 sth를 추가하십시오 CustomTextField Class.

@IBInspectable var hasError: Bool = false {
    didSet {

        if (hasError) {

            bottomBorder.backgroundColor = UIColor.red

        } else {

            bottomBorder.backgroundColor = UIColor(rgb: 0xE2DCD1)

        }

    }
}

그리고 CustomTextField의 인스턴스를 만든 후 오류 호출을 트리거하려면

textField.hasError = !textField.hasError

여기에 이미지 설명을 입력하십시오

그것이 누군가를 돕기를 바랍니다.)


답변

 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
   }
}

그리고 나서 이것을하십시오 :

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


답변

클래스 외부에서이 확장을 만들고 width를 원하는 borderWidth로 바꿀 수 있습니다.

스위프트 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)
    }
}

실물

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)
    }
}

그런 다음 이것을 viewDidLoad에 추가하십시오 .TextField를 UITextField 변수와 테두리에서 원하는 색상으로 바꾸십시오.

yourTextField.setBottomBorder(UIColor.blackColor())

이것은 기본적으로 텍스트 필드의 맨 아래에 해당 색상으로보기를 추가합니다.


답변

여기에 이미지 설명을 입력하십시오

목표 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;

빠른

        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