将UILabel/UITextField放在下一行而不是推出视图

bdv*_*bdv 5 cocoa-touch objective-c uitextfield core-text textkit

我正在创建一种自然语言形式,每当用户输入相当大的输入时,我希望整行都移动到下一行(就像一个UITextView).现在,我得到了这个结果:http://cl.ly/image/1E1n0W28360T

这表明存在两个明显的问题:一个:UITextField正在推动的元素应该转到下一行,其次,当向后间隔时,被"推开"的元素不会被"推回"到位.此外,UITextField退出时应该移动到下一行view.bounds.是否最好使用a UITextFieldUITextViewfor 是任意的.它应该适用于图2中的情况.

这是我想要实现的更具图形化的方法: 在此输入图像描述

我该如何解决这个问题?这是正确的方法吗?

更新

罗伯特的答案是非常好的,除了它仍然存在的一些错误之外还有一个问题,即它不灵活.我已经开始重构代码并尝试按照Robert的方法对a UITextField和a 进行子类化UITextView.

当继承代码,需要有一些代表团的UITextFieldUITextView.其次,句子的每个部分都需要UITextField在中间存在时进行分割,但我觉得这也可以硬编码到VC中.约束也需要转换为代码.

每当我得到所有这些问题中的任何一个的解决方案时,我都会更新问题并希望获得灵活的解决方案:)

Rob*_*ert 3

你的方法对我有用。

\n\n

假设您有一个UITextView显示可选择但不可编辑的完整句子, 包括输入的参数值。然后您就可以编辑UITextField每个表单参数。通过此设置,您可以将其留给 来UITextView处理文本流并使用UITextViews来处理输入。

\n\n

为了让UITextField出现在文本流中,技巧是将其隐藏\xe2\x80\x93 或者将其缩小到插入符号 \xe2\x80\x93 的宽度,并将其显示在文本的最后一个字符的位置参数的值。

\n\n
@interface ViewController ()\n\n@property (strong, nonatomic) IBOutlet UITextView *fullTextView;\n@property (strong, nonatomic) IBOutlet UITextField *friendField;\n\n// Using AutoLayout constraints to position the friendField\n@property (strong, nonatomic) IBOutlet NSLayoutConstraint *friendFieldLeadingConstraint;\n@property (strong, nonatomic) IBOutlet NSLayoutConstraint *friendFieldTopConstraint;\n@property (strong, nonatomic) IBOutlet NSLayoutConstraint *friendFieldWidthConstraint;\n\n@property (assign, nonatomic) CGFloat initialFriendFieldWidth;\n\n@end\n\n@implementation ViewController\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  // Store the intrinsic size of the friendField displaying the placeholder\n  // (there\'s probably a better way to this than storing the value on view load)\n  self.initialFriendFieldWidth = self.friendField.intrinsicContentSize.width;\n}\n\n- (IBAction)friendFieldEditingChanged:(UITextField *)friendField {\n\n  // Insert the friend name into the sentence\n  NSString *sentencePart1 = @"I\'m paying ";\n  NSString *sentencePart2 = @"\\n$ amount\\nfor description";\n  self.fullTextView.text = [@[sentencePart1, friendField.text, sentencePart2] componentsJoinedByString:@""];\n\n  // Render the fullTextView, so that we can retrieve the friend name\'s last character position\n  [self.fullTextView setNeedsLayout];\n  [self.fullTextView layoutIfNeeded];\n\n  // Retrieve the frame of the friend name\'s last character (in relation to the textView\'s coordinates)\n  UITextPosition *last = [self.fullTextView positionFromPosition:self.fullTextView.beginningOfDocument offset:sentencePart1.length + friendField.text.length];\n  UITextPosition *secondToLast = [self.fullTextView positionFromPosition:last offset:-1];\n  UITextRange *range = [self.fullTextView textRangeFromPosition:secondToLast toPosition:last];\n  CGRect rangeRect = [self.fullTextView firstRectForRange:range];\n\n  // Here comes the trick:\n  // The friendField\'s width will be reduced to the width of the caret and\n  // placed at the last character\'s position within the fullTextView. \n  // This way the UITextView handles the display of the full text, \n  // incl. the parameter values. And the UITextFields will handle the input,\n  // while only appearing as a caret.\n\n  // Retrieve the caret width\n  CGFloat width = [self.friendField caretRectForPosition:nil].size.width;\n  // If no text is entered, unfold friendField to reveal the placeholder\n  if (friendField.text.length == 0) {\n    width = self.initialFriendFieldWidth;\n  }\n\n  // Using AutoLayout constraints (see Main.storyboard)\n  // Note: A proper implementation needs to display the caret right where it is in \n  // relation to the input value. For now we only display it at the end of the value.\n  self.friendFieldLeadingConstraint.constant = - rangeRect.origin.x - rangeRect.size.width;\n  self.friendFieldTopConstraint.constant = - rangeRect.origin.y;\n  self.friendFieldWidthConstraint.constant = width;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

它看起来像这样:(突出显示文本字段尺寸)

\n\n

自然语言形式 - 1. 默认视图 - 2. 带输入

\n\n

您可以在此处下载完整的工作示例:https ://github.com/widescape/NaturalLanguageForm

\n