Skyscanner / SkyFloatingLabelTextField

A beautiful and flexible text field control implementation of "Float Label Pattern". Written in Swift.
Apache License 2.0
4.09k stars 540 forks source link

Align placeholder in center #228

Closed mojtaba-almoussawi closed 5 years ago

mojtaba-almoussawi commented 5 years ago

I want to align my placeholder in center of textField. How to achieve that? screen shot 2018-08-17 at 11 03 19 am

vindicatesociety commented 5 years ago

+1

k0nserv commented 5 years ago

Hey, since SkyFloatingLabelTextField inherits from UITextField the answer is the same as for UITextField i.e.

field.textAlignment = .center

or

field.textAlignment = NSTextAlignmentCenter;
mojtaba-almoussawi commented 5 years ago

I'am talking about the vertical alignment of placeholder not about the horizontal alignment!! As you can see i have already make it to be centered horizontally , but the placeholder is nearly at the bottom of the textfield , so my question was is there a way to keep it in middle of the textField.

That what i have done : 44254992-46267480-a20d-11e8-83ca-10d930e14613

And that what i want:

screen shot 2018-08-27 at 5 33 10 pm

k0nserv commented 5 years ago

RIght my bad, I think the issue here is that you are setting the background color. The text is centered inside the textfield itself, however the control allocates space above for the floating label which is why it looks off-center. If you remove the background color it should look okay.

mojtaba-almoussawi commented 5 years ago

Yes you are right, but i need to set the background color. The only solution i have so far is to make the textFields a subview in UIView, then clear the color of texFiled to be as you have mentioned, and set the background color of UIView. Is there another way to achieve that? thx

k0nserv commented 5 years ago

No there isn't really another solution for it, SkyFloatingLabelTexeField is intended to sit on the bg of it's parent view rather than have a custom background.

mojtaba-almoussawi commented 5 years ago

Ok @k0nserv, thanks.

adya commented 4 years ago

Hey, been trying to adapt SkyFloatingLabelTexeField in my project. Came across the very same issue.

For me the solution was to override placeholderRect(forBounds:) and editingRect(forBounds:)

override func editingRect(forBounds bounds: CGRect) -> CGRect {
    // When title is visible let `SkyFloatingLabelTexeField` handle positioning beneath the title
    isTitleVisible() ? super.editingRect(forBounds: bounds) : centeredFrame(in: bounds)
}

override func placeholderRect(forBounds bounds: CGRect) -> CGRect {
    centeredFrame(in: bounds)
}

Where centeredFrame(in: bounds) looks like:

private func centeredFrame(in: bounds) -> CGRect {
    var frame = bounds
    frame.size.height = bounds.height / 2
    frame.origin.y = (bounds.height - frame.height) / 2
    return frame
}
AnkurLahiry commented 3 years ago

Hey, been trying to adapt SkyFloatingLabelTexeField in my project. Came across the very same issue.

For me the solution was to override placeholderRect(forBounds:) and editingRect(forBounds:)

override func editingRect(forBounds bounds: CGRect) -> CGRect {
    // When title is visible let `SkyFloatingLabelTexeField` handle positioning beneath the title
    isTitleVisible() ? super.editingRect(forBounds: bounds) : centeredFrame(in: bounds)
}

override func placeholderRect(forBounds bounds: CGRect) -> CGRect {
    centeredFrame(in: bounds)
}

Where centeredFrame(in: bounds) looks like:

private func centeredFrame(in: bounds) -> CGRect {
    var frame = bounds
    frame.size.height = bounds.height / 2
    frame.origin.y = (bounds.height - frame.height) / 2
    return frame
}

The earth is saved 😄

Thisura98 commented 1 year ago

I don't know if anyone would find this helpful, but I used a slightly modified version of adya's comment and wanted to contribute. Btw, call hideIcon(), hideLine() to get rid of those elements in the text field.

final class MaterialTextField: SkyFloatingLabelTextFieldWithIcon{

    private let yAdjustment = 2.0

    override func titleLabelRectForBounds(_ bounds: CGRect, editing: Bool) -> CGRect {
        return adjustedFrame(in: super.titleLabelRectForBounds(bounds, editing: editing))
    }

    override func editingRect(forBounds bounds: CGRect) -> CGRect {
        if (text?.isEmpty ?? false){
            return placeholderRect(forBounds: bounds)
        }

        return adjustedFrame(in: super.editingRect(forBounds: bounds))
    }

    override func textRect(forBounds bounds: CGRect) -> CGRect {
        return adjustedFrame(in: super.textRect(forBounds: bounds))
    }

    override func placeholderRect(forBounds bounds: CGRect) -> CGRect {
        return centeredFrame(in: bounds)
    }

    /**
     https://github.com/Skyscanner/SkyFloatingLabelTextField/issues/228#issuecomment-619966834
     */
    private func centeredFrame(in: CGRect) -> CGRect {
        var frame = bounds
        frame.size.height = bounds.height / 2
        frame.origin.y = (bounds.height - frame.height) / 2
        return frame
    }

    private func adjustedFrame(in frame: CGRect) -> CGRect {
        var copy = frame
        copy.origin.y += yAdjustment
        return copy
    }

    func hideIcon(){
        iconWidth = 0
        iconImage = nil
        iconMarginLeft = 0
        iconMarginBottom = 0
    }

    func hideLine(){
        lineColor = UIColor.clear
        selectedLineColor = UIColor.clear
        lineHeight = 0
        selectedLineHeight = 0
    }

}
keremdemirios commented 1 year ago

SkyFloatingLabelTexeFieldHey, projeme uyum sağlamaya çalışıyorum . Aynı sorunla karşılaştım.

Benim için çözüm geçersiz kılmaktı placeholderRect(forBounds:)veeditingRect(forBounds:)

override func editingRect(forBounds bounds: CGRect) -> CGRect {
    // When title is visible let `SkyFloatingLabelTexeField` handle positioning beneath the title
    isTitleVisible() ? super.editingRect(forBounds: bounds) : centeredFrame(in: bounds)
}

override func placeholderRect(forBounds bounds: CGRect) -> CGRect {
    centeredFrame(in: bounds)
}

Nerede centeredFrame(in: bounds)görünüyor:

private func centeredFrame(in: bounds) -> CGRect {
    var frame = bounds
    frame.size.height = bounds.height / 2
    frame.origin.y = (bounds.height - frame.height) / 2
    return frame
}

Where exactly should we place these codes?

adya commented 1 year ago

In your subclass of SkyFloatingLabelTexeField