iOS 8中具有动态高度的自定义inputView
Posted
技术标签:
【中文标题】iOS 8中具有动态高度的自定义inputView【英文标题】:Custom inputView with dynamic height in iOS 8 【发布时间】:2014-07-15 10:37:24 【问题描述】:我的 UITextFields
的自定义 inputView 有一些问题。根据用户需要在UITextField
中输入的文本,inputView 仅显示所需的字母。这意味着对于短文本,只有一行字母的 inputView 就足够了,较长的文本可能需要 2 甚至 3 行,因此 inputView 的高度是可变的。
因为我期待更好的性能,所以每个 textField 只使用一个 inputView 实例。这样创建必须只发生一次,这使得有时需要直接访问 inputView 更容易。 inputView 设置在- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
中,设置了它需要的高度并会显示出来。
效果很好,但在 ios8 上不行。有一些包含 inputView 的系统视图在更改时不会更新其框架以匹配 inputView 的边界(第一次有效)。
我知道可以通过每个 textField 使用我的 inputView 的一个实例来解决这个问题。但我问是否有推荐/更好的方法来调整框架或将其更改报告给包含视图。也许这是一个 iOS8 的 bug,可以在发布之前修复?
这里有一些重现问题的示例代码:
自定义输入视图
@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, 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, 290, 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, 290, 30);
[self.view addSubview:button];
- (void)endEditing
[self.view endEditing:YES];
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
[[CustomInputView sharedInputView] setupForTextField:textField];
return YES;
【问题讨论】:
你有没有找到调整 inputView 大小的解决方案?我需要 iPad 的固定 inputView 高度。 如果您需要固定高度,它应该可以工作 - inputView 将保持在您创建时指定的高度。如果您以后需要更改高度,我仍然不知道解决方案。我采取了为每个 textField 创建一个 inputView 的解决方法,这对我的情况来说没问题... 【参考方案1】:我在将自定义键盘从 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://***.com/a/40359382/153354。
【讨论】:
【参考方案2】:我发现在 iOS 9 及更高版本上调整 inputView 的大小至关重要的另一件事是将 allowSelfSizing 设置为 true:
if #available(iOS 9.0, *)
self.inputView?.allowsSelfSizing = true
【讨论】:
这对我有用。不要忘记您的视图必须是UIInputView
的子类。以上是关于iOS 8中具有动态高度的自定义inputView的主要内容,如果未能解决你的问题,请参考以下文章
UISearchBar 的自定义 InputView 在 iOS7 中不起作用
在具有动态高度的 IB uitableviewcell 中使用带有 XIB 的自定义视图