Objective C:如何创建多行的UITextField?

24

如何实现类似 iPhone 信息应用程序中看到的多行文本框?

可能重复:
如何创建多行UITextfield?

enter image description here

似乎当输入长度超过一定长度时,会自动创建第二行。

编辑:更新以阐明我在使用UITextView时遇到的挑战。

对于我来说,我想要将UITextView的感觉和外观建模为下面所示的样子。我不确定如何按照建议使用UITextView实现。例如:

1)如何在我的文本需要溢出到下一行时动态扩展框

2)如何添加下面显示的边框和样式

3)如何将文本框附加到键盘正上方(而不是在视图中)

我知道Instagram也有这个功能,如果有人能指点我正确的方向,那就太好了。先谢谢了。

enter image description here


你达到了想要的目标了吗? - Nicolas S
2个回答

28

查看这些答案:

如何创建多行UITextfield?

如何创建多行UITextfield?

http://brettschumann.com/blog/2010/01/15/iphone-multiline-textbox-for-sms-style-chat 您也可以参考BrettSchumann的博客提供的信息。

此外,绝对要尝试一下Three20,它是许多应用程序(如Facebook)中使用的优秀库。


编辑:添加了BrettSchumann博客的摘录

#import <uikit uikit.h="">
@interface MultilineTextboxViewController : UIViewController {
    IBOutlet UIView *viewTable;
    IBOutlet UIView *viewForm;
    IBOutlet UITextView *chatBox;
    IBOutlet UIButton   *chatButton;
}

@property (nonatomic, retain) UIView *viewTable;
@property (nonatomic, retain) UIView *viewForm;
@property (nonatomic, retain) UITextView *chatBox;
@property (nonatomic, retain) UIButton *chatButton;

- (IBAction)chatButtonClick:(id)sender;
@end
</uikit>

做完这些操作之后,我们在设置所有内容时,同时将它们添加到我们的主文件(.m)中,不要忘记也进行解除分配。

@synthesize viewTable;
@synthesize viewForm;
@synthesize chatBox;
@synthesize chatButton;

- (void)dealloc{
    [viewTable release];
    [viewForm release];
    [chatBox release];
    [chatButton release];
    [super dealloc];
}

在(void)viewDidLoad方法中,我们需要添加一些通知观察者,以便我们能够看到键盘何时显示或隐藏以及用户何时按下键盘上的键。

- (void)viewDidLoad {
    //set notification for when keyboard shows/hides
    [[NSNotificationCenter defaultCenter] addObserver:self 
                        selector:@selector(keyboardWillShow:) 
                        name:UIKeyboardWillShowNotification 
                        object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self 
                        selector:@selector(keyboardWillHide:) 
                        name:UIKeyboardWillHideNotification 
                        object:nil];

    //set notification for when a key is pressed.
    [[NSNotificationCenter defaultCenter] addObserver:self 
                        selector: @selector(keyPressed:) 
                        name: UITextViewTextDidChangeNotification 
                        object: nil];

    //turn off scrolling and set the font details.
    chatBox.scrollEnabled = NO;
    chatBox.font = [UIFont fontWithName:@"Helvetica" size:14]; 

    [super viewDidLoad];
}

当 TextView 获得焦点时,键盘会显示。由于 TextView 和按钮都在屏幕下面的 viewForm 中,因此键盘将升起并覆盖它们。所以我们想要做的就是调整 viewTable 的高度和 viewForm 的位置。我们使用以下方法来实现这一点。

-(void) keyboardWillShow:(NSNotification *)note{
    // get keyboard size and loction
    CGRect keyboardBounds;
    [[note.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &keyboardBounds];

    // get the height since this is the main value that we need.
    NSInteger kbSizeH = keyboardBounds.size.height;

    // get a rect for the table/main frame
    CGRect tableFrame = viewTable.frame;
    tableFrame.size.height -= kbSizeH;

    // get a rect for the form frame
    CGRect formFrame = viewForm.frame;
    formFrame.origin.y -= kbSizeH;

    // animations settings
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:0.3f];

    // set views with new info
    viewTable.frame = tableFrame;
    viewForm.frame = formFrame;

    // commit animations
    [UIView commitAnimations];
}
现在显示了键盘并调整了我们的视图,我们想要捕获用户输入的文本,并查看是否需要对聊天框进行任何调整。幸运的是,我们可以使用CGSize对象,将一些文本传递给它,并告诉该对象我们想要限制文本的尺寸,从而可以计算得出高度。现在就是试错的时候了。该行的变化与字体大小有关,而您的CGSize对象的宽度将随着UITextview的宽度而变化,因此您需要进行一些实验。代码中使用的值12是我的chatBox起始高度和基于我设置的字体的行高之间的高度差。
-(void) keyPressed: (NSNotification*) notification{
    // get the size of the text block so we can work our magic
    CGSize newSize = [chatBox.text 
                sizeWithFont:[UIFont fontWithName:@"Helvetica" size:14] 
                constrainedToSize:CGSizeMake(222,9999) 
                lineBreakMode:UILineBreakModeWordWrap];
    NSInteger newSizeH = newSize.height;
    NSInteger newSizeW = newSize.width;

    // I output the new dimensions to the console 
    // so we can see what is happening
    NSLog(@"NEW SIZE : %d X %d", newSizeW, newSizeH);
    if (chatBox.hasText)
    {
        // if the height of our new chatbox is
        // below 90 we can set the height
        if (newSizeH <= 90)
        {
            [chatBox scrollRectToVisible:CGRectMake(0,0,1,1) animated:NO];

            // chatbox
            CGRect chatBoxFrame = chatBox.frame;
            NSInteger chatBoxH = chatBoxFrame.size.height;
            NSInteger chatBoxW = chatBoxFrame.size.width;
            NSLog(@"CHAT BOX SIZE : %d X %d", chatBoxW, chatBoxH);
            chatBoxFrame.size.height = newSizeH + 12;
            chatBox.frame = chatBoxFrame;

            // form view
            CGRect formFrame = viewForm.frame;
            NSInteger viewFormH = formFrame.size.height;
            NSLog(@"FORM VIEW HEIGHT : %d", viewFormH);
            formFrame.size.height = 30 + newSizeH;
            formFrame.origin.y = 199 - (newSizeH - 18);
            viewForm.frame = formFrame;

            // table view
            CGRect tableFrame = viewTable.frame;
            NSInteger viewTableH = tableFrame.size.height;
            NSLog(@"TABLE VIEW HEIGHT : %d", viewTableH);
            tableFrame.size.height = 199 - (newSizeH - 18);
            viewTable.frame = tableFrame;
        }

        // if our new height is greater than 90
        // sets not set the height or move things
        // around and enable scrolling
        if (newSizeH > 90)
        {
            chatBox.scrollEnabled = YES;
        }
    }
}

一旦我们输入完内容并且用户按下发送按钮,我们想要对这些文本进行某些操作,同时关键字将会消失而我们希望将视图重置为最初状态。那么我们该如何做呢?

- (IBAction)chatButtonClick:(id)sender{
    // hide the keyboard, we are done with it.
    [chatBox resignFirstResponder];
    chatBox.text = nil;

    // chatbox
    CGRect chatBoxFrame = chatBox.frame;
    chatBoxFrame.size.height = 30;
    chatBox.frame = chatBoxFrame;
    // form view
    CGRect formFrame = viewForm.frame;
    formFrame.size.height = 45;
    formFrame.origin.y = 415;
    viewForm.frame = formFrame;

    // table view
    CGRect tableFrame = viewTable.frame;
    tableFrame.size.height = 415;
    viewTable.frame = tableFrame;
}

resignFirstResponder将隐藏键盘,然后我们只需要将视图和chatBox设置回其原始状态。

-(void) keyboardWillHide:(NSNotification *)note{
    // get keyboard size and loction

    CGRect keyboardBounds;
    [[note.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &keyboardBounds];

    // get the height since this is the main value that we need.
    NSInteger kbSizeH = keyboardBounds.size.height;

    // get a rect for the table/main frame
    CGRect tableFrame = viewTable.frame;
    tableFrame.size.height += kbSizeH;

    // get a rect for the form frame
    CGRect formFrame = viewForm.frame;
    formFrame.origin.y += kbSizeH;

    // animations settings
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:0.3f];

    // set views with new info
    viewTable.frame = tableFrame;
    viewForm.frame = formFrame;

    // commit animations
    [UIView commitAnimations];
}

这里就是你想要的,一个TextView一开始只有一行,但当用户输入文本后会增长到最大大小,然后成为一个可滚动的TextView。


2
如果您能够写出这些URL的摘要,那就太好了。也许有一天它们会失效。只是一个想法。不过还是谢谢您提供这些URL,帮助我找到了解决方案。 - pqsk

23

UITextField 不允许你写入多行文本...但是你可以使用 UITextView 替代,然后使用 NSString -sizeWithFont 函数来了解需要的空间大小。

就像这样:

CGSize size = [yourTextView.text sizeWithFont:yourTextView.font];
CGRect f = yourTextView.frame;
f.size.height = ceil(size.width/f.size.width)*size.height
yourTextView.frame = f;

我没有尝试过这段代码,但我以前已经使用过类似的代码。希望我的信息对你有用:)


谢谢你的帮助!我的想法是为用户提供一个空的输入字段去输入值,对于你的代码而言,我的初始TextView框架应该为零,因为还没有文本吧? - Zhen
1
对于iOS8+,请使用以下代码替换上述代码:CGSize size = [_titleField.text sizeWithAttributes:@{NSFontAttributeName: _titleField.font}]; CGFloat newWidth = _titleField.bounds.size.width == 0 ? applicationFrame.size.width - 56 : _titleField.bounds.size.width; CGFloat titleFieldHeight = ceil(size.width /newWidth)* size.height;您可以在自动布局中使用titleFieldHeight作为度量标准。 - elliotrock
这并没有涉及到帧高度取决于换行的事实(并且根据换行选项不同会有所不同)。它也没有处理默认插入(在UITextView上相对较大)。但是,在大多数情况下,这将是有效的;添加的插入松弛实际上有助于隐藏这不是精确解决方案的事实。 - meaning-matters
@elliotrock 为什么你写 _textField 而不是 ...View??? - meaning-matters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接