a

Câu hỏi Chèn văn bản cho UITextField?


Tôi muốn nhấn chìm bản văn của một UITextField.

Điều này có thể không?


364
2018-04-22 20:55


gốc


stackoverflow.com/questions/7565645/… - Fattie


Các câu trả lời:


Ghi đè -textRectForBounds: sẽ chỉ thay đổi nội dung của văn bản trình giữ chỗ. Để thay đổi nội dung của văn bản có thể chỉnh sửa, bạn cũng cần phải ghi đè -editingRectForBounds:

// placeholder position
- (CGRect)textRectForBounds:(CGRect)bounds {
     return CGRectInset(bounds, 10, 10);
}

// text position
- (CGRect)editingRectForBounds:(CGRect)bounds {
     return CGRectInset(bounds, 10, 10);
}

575
2017-10-19 14:56



Giải pháp này làm việc cho tôi, mặc dù tôi đã sử dụng một giá trị trả về của CGRectInset (giới hạn, 9, 0); Tôi cũng cần thiết lập giá trị này cho textRectForBounds, editingRectForBounds và placeholderRectForBounds. - RyJ
Giải pháp này không chơi tốt với clearButton. Văn bản bên trong nút lớp phủ TextField. - Piotr
Tôi nghĩ, việc ghi đè các phương pháp trên sẽ khiến cuộn chậm, nếu UITextField đang cư trú trong một UIScrollView. - Bharat Dodeja
Để đặt ClearButton: - (CGRect)clearButtonRectForBounds:(CGRect)bounds { return CGRectMake(x, y, w, h); }  Tìm thấy ở đây: stackoverflow.com/questions/5361369/… - Miros
Tôi đề nghị gọi [super textRectForBounds: bounds] và [super editingRectForBounds: bounds] trước khi gọi CGRectInset (giới hạn, 10, 10). Điều này sẽ khắc phục vấn đề lớp phủ nút rõ ràng. - mrvincenzo


Tôi đã có thể làm điều đó thông qua:

myTextField.layer.sublayerTransform = CATransform3DMakeTranslation(5, 0, 0);

Tất nhiên hãy nhớ nhập QuartzCore và cũng thêm Khung vào dự án của bạn.


283
2017-11-22 15:21



Cảm ơn .. đó là một trợ giúp tuyệt vời ... - Kanan Vora
1 cho sự sáng tạo, nhưng đây là một chút vấn đề, nó di chuyển cũng xóa nút bên trong textfield - Nikita
bạn có thể làm myTextField.layer.sublayers mà là một mảng của tất cả các sublayers ... và nếu UIImageView của nó <- Tôi giả sử X là một hình ảnh .. hoặc có thể UIButton ... hoặc bạn có thể lặp lại kỹ lưỡng từng cái và xem cái nào thuộc về phân lớp nào ... nhưng myfield.layer.sublayerTransform tất cả các lớp con và do đó nút X cũng di chuyển. - chuthan20
Đây là giải pháp tốt nhất mà không cần phân lớp và không yêu cầu các lượt xem thừa, không cần thiết sẽ được đặt trên màn hình! +1! - Rambatino
@ jeet.chanchawat Nút X ở bên phải trong bức ảnh này .. developer.apple.com/library/content/documentation/… - chuthan20


Trong một lớp có nguồn gốc từ UITextField, ghi đè ít nhất hai phương thức sau:

- (CGRect)textRectForBounds:(CGRect)bounds;
- (CGRect)editingRectForBounds:(CGRect)bounds;

Nó có thể đơn giản như thế này nếu bạn không có nội dung bổ sung:

return CGRectInset(bounds , 10, 10);

UITextField cung cấp một số phương pháp định vị bạn có thể ghi đè lên.


162
2018-04-22 21:04



vâng, nếu bạn không ghi đè editRectForBounds, bạn sẽ nhận được văn bản khi chỉnh sửa ở trên cùng bên trái của trường văn bản. - (CGRect) editRectForBounds: (CGRect) giới hạn {return CGRectInset (giới hạn, 10, 10); } - Mark W
Chỉ cần chỉnh sửa câu trả lời để tích hợp phương thức editingRectForBounds vào - ıɾuǝʞ
Điều này dường như với tôi là một hack khủng khiếp - bạn cũng sẽ cần phải ghi đè - (CGRect)borderRectForBounds:(CGRect)bounds; - (CGRect)placeholderRectForBounds:(CGRect)bounds; - (CGRect)clearButtonRectForBounds:(CGRect)bounds; - (CGRect)leftViewRectForBounds:(CGRect)bounds; - (CGRect)rightViewRectForBounds:(CGRect)bounds; - Zorayr


Nếu bạn chỉ cần một lề trái, bạn có thể thử điều này:

UItextField *textField = [[UITextField alloc] initWithFrame:...];
UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, textField.frame.size.height)];
leftView.backgroundColor = textField.backgroundColor;
textField.leftView = leftView;
textField.leftViewMode = UITextFieldViewModeAlways;

Nó làm việc cho tôi. Tôi hy vọng điều này có thể hữu ích.


149
2018-03-01 22:06



Điều này dễ dàng hơn nhiều so với phân lớp phụ chỉ để có được một inset, và cho phép bạn thêm bất kỳ khung nhìn tùy ý nào ở bên trái (bạn cũng có thể sử dụng rightView để đặt một cái gì đó ở bên phải). Tốt hơn câu trả lời được chấp nhận IMHO. - Kenny Grant
+1 dễ dàng, không có phân lớp phụ và được thiết kế để hoạt động với các thuộc tính textfield (chứ không phải là 'hacking'). - So Over It
Dòng thứ ba phải là leftView.backgroundColor = textField.backgroundColor;... Khác hơn là giải pháp tuyệt vời ... Cảm ơn (: - Aviel Gross
Không hoàn toàn thanh lịch / kỹ lưỡng như câu trả lời của azdev, nhưng là một giải pháp tuyệt vời cho một trường hợp thông thường và đơn giản! - Rembrandt Q. Einstein
Phân lớp sẽ giúp bạn tiết kiệm rất nhiều thời gian cho câu trả lời này, trừ khi bạn có một hộp văn bản duy nhất mà bạn cần. - Crake


Làm thế nào về một @IBInspectable, @IBDesignable lớp học nhanh.

@IBDesignable
class TextField: UITextField {
    @IBInspectable var insetX: CGFloat = 6 {
       didSet {
         layoutIfNeeded()
       }
    }
    @IBInspectable var insetY: CGFloat = 6 {
       didSet {
         layoutIfNeeded()
       }
    }

    // placeholder position
    override func textRectForBounds(bounds: CGRect) -> CGRect {
        return CGRectInset(bounds , insetX , insetY)
    }

    // text position
    override func editingRectForBounds(bounds: CGRect) -> CGRect {
        return CGRectInset(bounds , insetX , insetY)
    }
}

Bạn sẽ thấy điều này trong bảng phân cảnh của mình.

enter image description here

Cập nhật - Swift 3

@IBDesignable
class TextField: UITextField {
    @IBInspectable var insetX: CGFloat = 0
    @IBInspectable var insetY: CGFloat = 0

    // placeholder position
    override func textRect(forBounds bounds: CGRect) -> CGRect {
        return bounds.insetBy(dx: insetX, dy: insetY)
    }

    // text position
    override func editingRect(forBounds bounds: CGRect) -> CGRect {
        return bounds.insetBy(dx: insetX, dy: insetY)
    }
}

83
2018-02-10 15:20



Tôi tìm thấy hiệu ứng trên Y không mong muốn, tôi không muốn thu nhỏ âm đạo cho văn bản, thay vì di chuyển nó xuống đường cơ sở của trường. Tôi đã điều chỉnh các triển khai thành let rect = CGRect(x: bounds.minX, y: bounds.minY + insetY, width: bounds.width, height: bounds.height) return CGRectInset(rect , insetX , 0) - Chris Wagner
Và thêm này quá nếu yo đang sử dụng giữ chỗ `ghi đè lên func placeholderRectForBounds (giới hạn: CGRect) -> CGRect {return CGRectInset (ràng buộc, insetX, insetY)}` - RameshVel
Hoạt động hoàn hảo. - dhruvvyas90


Nếu bạn có nút rõ ràng, câu trả lời được chấp nhận sẽ không hoạt động cho bạn. Chúng ta cũng nên bảo vệ chống lại Apple thay đổi mọi thứ trong tương lai bằng cách gọi super.

Vì vậy, để đảm bảo văn bản không chồng chéo nút rõ ràng, hãy lấy giá trị 'mặc định' từ super trước tiên, sau đó điều chỉnh khi cần thiết.

Mã này sẽ thêm một miếng chèn 10px ở trên cùng, bên trái và dưới cùng của trường văn bản:

@interface InsetTextField : UITextField

@end


@implementation InsetTextField

// Placeholder position
- (CGRect)textRectForBounds:(CGRect)bounds {
    CGRect rect = [super textRectForBounds:bounds];
    UIEdgeInsets insets = UIEdgeInsetsMake(10, 10, 10, 0);

    return UIEdgeInsetsInsetRect(rect, insets);
}

// Text position
- (CGRect)editingRectForBounds:(CGRect)bounds {
    CGRect rect = [super editingRectForBounds:bounds];
    UIEdgeInsets insets = UIEdgeInsetsMake(10, 10, 10, 0);

    return UIEdgeInsetsInsetRect(rect, insets);
}

// Clear button position
- (CGRect)clearButtonRectForBounds:(CGRect)bounds {
    CGRect rect = [super clearButtonRectForBounds:bounds];

    return CGRectOffset(rect, -5, 0);
}

@end

Lưu ý: UIEdgeInsetsMake nhận các tham số theo thứ tự: hàng đầu, trái, đáy, đúng.


26
2017-07-07 16:45



Cảm ơn nhiều! Tôi đã sử dụng câu trả lời được chấp nhận và nhận thấy rằng nó không chiếm nút rõ ràng. Câu trả lời này có và nên được coi là câu trả lời được chấp nhận. - Alexander
Sử dụng textRectForBounds: và editingRectForBounds: phương pháp không có  clearButtonRectForBounds: trên iOS 7+ đã hoạt động cho tôi. - Stunner
clearButtonRectForBounds: chỉ giúp di chuyển nút rõ ràng sang trái một chút. Bạn có thể muốn bỏ nó ra. Trường văn bản của tôi nằm trên nền tối và nút rõ ràng cần một chút đệm phụ ở bên phải. - Chris Nolet


Nghĩ rằng tôi sẽ cung cấp một giải pháp Swift

import UIKit

class TextField: UITextField {
    let inset: CGFloat = 10

    // placeholder position
    override func textRectForBounds(bounds: CGRect) -> CGRect {
        return CGRectInset(bounds , inset , inset)
    }

    // text position
    override func editingRectForBounds(bounds: CGRect) -> CGRect {
        return CGRectInset(bounds , inset , inset)
    }

    override func placeholderRectForBounds(bounds: CGRect) -> CGRect {
        return CGRectInset(bounds, inset, inset) 
    }
}

17
2017-09-04 21:38



Đừng quên override func placeholderRectForBounds(bounds: CGRect) -> CGRect { return CGRectInset(bounds, inset, inset) } - Eugene Braginets
Trong Swift 3 bạn phải sử dụng phương thức 'CGRect.insetBy ()' - Den
Ít nhất trong iOS 11, nếu bạn ghi đè textRectForBounds, trình giữ chỗ cũng bị ảnh hưởng - vì vậy việc thêm ghi đè trình giữ chỗ sẽ chèn phần giữ chỗ khác thêm 10pt nữa. Nếu đó là những gì bạn đang tìm kiếm, 🏼, nhưng nếu không, nó là tốt để được nhận thức. - DesignatedNerd


Sử dụng textRectForBounds: là cách tiếp cận chính xác. Tôi đã bọc nó lên trong lớp con của tôi để bạn có thể sử dụng đơn giản textEdgeInsets. Xem SSTextField.


14
2018-05-21 23:59



Cách tiếp cận này, cùng với việc sử dụng cocoapods để nhập khẩu nhóm SSToolkit, hoạt động tốt - tôi nghĩ đây là cách tốt nhất để đi. - Chris
Cảm ơn Chris! Thật vui khi bạn thấy nó hữu ích. - Sam Soffes


Một cách tiếp cận tốt để thêm đệm vào UITextField là phân lớp UITextField và thêm một thuộc tính edgeInsets. Sau đó bạn thiết lập edgeInsets và UITextField sẽ được vẽ cho phù hợp. Điều này cũng sẽ hoạt động chính xác với một chế độ xem bên trái hoặc chế độ xem bên phải tùy chỉnh.

OSTextField.h

#import <UIKit/UIKit.h>

@interface OSTextField : UITextField

@property (nonatomic, assign) UIEdgeInsets edgeInsets;

@end

OSTextField.m

#import "OSTextField.h"

@implementation OSTextField

- (id)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        self.edgeInsets = UIEdgeInsetsMake(0, 0, 0, 0);
    }
    return self;
}

-(id)initWithCoder:(NSCoder *)aDecoder{
    self = [super initWithCoder:aDecoder];
    if(self){
        self.edgeInsets = UIEdgeInsetsMake(0, 0, 0, 0);
    }
    return self;
}

- (CGRect)textRectForBounds:(CGRect)bounds {
    return [super textRectForBounds:UIEdgeInsetsInsetRect(bounds, self.edgeInsets)];
}

- (CGRect)editingRectForBounds:(CGRect)bounds {
    return [super editingRectForBounds:UIEdgeInsetsInsetRect(bounds, self.edgeInsets)];
}

@end

11
2017-07-09 21:25



Câu trả lời tốt. Cung cấp tài sản bị thiếu :-) - phatmann