How can I move the clear button in a UITextField?

混江龙づ霸主 提交于 2019-12-04 00:32:15

I haven't seen this, and a screen shot would be helpful. But, the quick answer is that you can inspect the subviews array of the UITextField, find the subview that contains the clear button, and adjust its frame.origin.

Edit: It seems I've been downvoted for this answer (written in 2010). This is of not an "officially" approved method because you're manipulating private objects, but it's not detectable by Apple. The main risk is that the view hierarchy might be changed at some point.

As stated by @Luda the correct way is to subclass UITextField and override - (CGRect)clearButtonRectForBounds:(CGRect)bounds. However the bounds passed in to the method are those of the view itself and not the button. Therefore you should call super to get the OS provided size (to avoid distortion of the image) and then adjust the origin to suit your needs.

e.g.

- (CGRect)clearButtonRectForBounds:(CGRect)bounds {
    CGRect originalRect = [super clearButtonRectForBounds:bounds];
    return CGRectOffset(originalRect, -10, 0); //shift the button 10 points to the left
}

Apple docs state:

Discussion You should not call this method directly. If you want to place the clear button in a different location, you can override this method and return the new rectangle. Your method should call the super implementation and modify the returned rectangle’s origin only. Changing the size of the clear button may cause unnecessary distortion of the button image.

I had subclassed the UITextField and override the function clearButtonRectForBounds:.

.h

#import <UIKit/UIKit.h>

@interface TVUITextFieldWithClearButton : UITextField

@end

.m

#import "TVUITextFieldWithClearButton.h"

@implementation TVUITextFieldWithClearButton

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

- (void)awakeFromNib
{
    self.clearButtonMode = UITextFieldViewModeWhileEditing;
}


- (CGRect)clearButtonRectForBounds:(CGRect)bounds
{
    return CGRectMake(bounds.size.width/2-20 , bounds.origin.y-3, bounds.size.width, bounds.size.height);
}

@end

The answer from Van Du Tran in Swift 4:

class CustomTextField: UITextField {


override func clearButtonRect(forBounds bounds: CGRect) -> CGRect {
    let originalRect = super.clearButtonRect(forBounds: bounds)

    return originalRect.offsetBy(dx: -8, dy: 0)
}

}

Subclass UITextField and override this method:

- (CGRect)clearButtonRectForBounds:(CGRect)bounds
{
    return CGRectMake(bounds.origin.x - 10, bounds.origin.y, bounds.size.width, bounds.size.height);
}

return the CGRect that matches your needs.

Swift 4 version would be

import UIKit

class LoginTextField: UITextField {

    override func clearButtonRect(forBounds bounds: CGRect) -> CGRect {
        return CGRect(x: xPos, y:yPos, width: yourWidth, height: yourHeight)
    }

}

Swift 4, 5

Subclass UITextField (Working Perfectly, Tested)

class textFieldWithCrossButtonAdjusted: UITextField {

    override func clearButtonRect(forBounds bounds: CGRect) -> CGRect {

        let originalRect = super.clearButtonRect(forBounds: bounds)

        //move 10 points left

        return originalRect.offsetBy(dx: -10, dy: 0)
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!