我的自定义inputView for UITextFields有些麻烦.根据用户需要在UITextField中输入的文本,inputView仅显示所需的字母.这意味着对于短文本,只有一行字母的inputView就足够了,较长的文本可能需要2行甚至3行,因此inputView的高度是变量.
由于我期望性能更好,因此每个textField只使用一个inputView实例.这样创建必须只发生一次,这使得有时需要直接访问inputView更容易. inputView设置在 – (BOOL)textFieldShouldBeginEditing:(UITextField *)textField中,设置其所需的高度并将显示.
这非常有效,但不适用于iOS8.有一些包含inputView的系统视图在更改时不会更新其框架以匹配inputView的边界(第一次工作).
我知道可以通过每个textField使用我的inputView的一个实例来修复.但我问是否有一种推荐/更好的方法来调整框架或将其更改报告给包含视图.也许这是一个iOS8错误,可以修复直到发布?
以下是重现问题的示例代码:
CustomInputView
@implementation CustomInputView
+ (CustomInputView*)sharedInputView{
static CustomInputView *sharedInstance;
static dispatch_once_t oncetoken;
dispatch_once(&oncetoken,^{
sharedInstance = [[CustomInputView alloc] init];
});
return sharedInstance;
}
- (id)init
{
self = [super init];
if (self) {
self.backgroundColor = [UIColor greenColor];
}
return self;
}
- (void)setupForTextField:(UITextField*)textField{
CGFloat height;
if(textField.tag == 1){
height = 100;
}else height = 50;
self.frame = CGRectMake(0,320,height);
}
@end
TestViewController代码
- (void)viewDidLoad
{
[super viewDidLoad];
UITextField *tf = [[UITextField alloc] initWithFrame:CGRectMake(15,50,290,30)];
tf.text = @"bigKeyboard";
tf.inputView = [CustomInputView sharedInputView];
tf.layer.borderWidth = 1;
tf.layer.borderColor = [UIColor lightGrayColor].CGColor;
tf.delegate = self;
tf.tag = 1;
[self.view addSubview:tf];
tf = [[UITextField alloc] initWithFrame:CGRectMake(15,100,30)];
tf.text = @"smallKeyboard";
tf.inputView = [CustomInputView sharedInputView];
tf.layer.borderWidth = 1;
tf.layer.borderColor = [UIColor lightGrayColor].CGColor;
tf.delegate = self;
tf.tag = 2;
[self.view addSubview:tf];
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
[button setTitle:@"dismissKeyboard" forState:UIControlStatenormal];
[button addTarget:self action:@selector(endEditing) forControlEvents:UIControlEventTouchUpInside];
button.frame = CGRectMake(15,150,30);
[self.view addSubview:button];
}
- (void)endEditing{
[self.view endEditing:YES];
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
[[CustomInputView sharedInputView] setupForTextField:textField];
return YES;
}
解决方法
我在将自定义键盘从iOS 8调整到iOS 10时遇到了类似的问题.我认为正确的解决方案是让输入视图提供适当的intrinsicContentSize并在您想要更改视图高度时更改(并使其无效!)该值.示例代码:
class CustomInputView: UIInputView {
var intrinsicHeight: CGFloat = 200 {
didSet {
self.invalidateIntrinsicContentSize()
}
}
init() {
super.init(frame: CGRect(),inputViewStyle: .keyboard)
self.translatesAutoresizingMaskIntoConstraints = false
}
required init?(coder: NSCoder) {
super.init(coder: coder)
self.translatesAutoresizingMaskIntoConstraints = false
}
override var intrinsicContentSize: CGSize {
return CGSize(width: UIViewNoIntrinsicmetric,height: self.intrinsicHeight)
}
}
class ViewController: UIViewController {
@IBOutlet weak var textView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
textView.becomeFirstResponder()
let inputView = CustomInputView()
// To make the view's size more clear.
inputView.backgroundColor = UIColor(red: 0.5,green: 1,blue: 0.5,alpha: 1)
textView.inputView = inputView
// To demonstrate a change to the view's intrinsic height.
dispatchQueue.main.asyncAfter(deadline: dispatchTime.Now() + .seconds(2)) {
inputView.intrinsicHeight = 400
}
}
}
另见https://stackoverflow.com/a/40359382/153354.