dre*_*ewh 512 cocoa-touch uitextview uikit ios autolayout
有没有一种很好的方法来调整a的大小UITextView以符合其内容?比方说我有一个UITextView包含一行文字:
"Hello world"
Run Code Online (Sandbox Code Playgroud)
然后我添加另一行文字:
"Goodbye world"
Run Code Online (Sandbox Code Playgroud)
在Cocoa Touch中是否有一个好方法rect可以保存文本视图中的所有行,以便我可以相应地调整父视图?
再举一个例子,查看日历应用程序中事件的注释字段 - 注意单元格(及其UITextView包含)如何扩展以包含注释字符串中的所有文本行.
jhi*_*erd 601
这适用于iOS 6.1和iOS 7:
- (void)textViewDidChange:(UITextView *)textView
{
CGFloat fixedWidth = textView.frame.size.width;
CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
CGRect newFrame = textView.frame;
newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
textView.frame = newFrame;
}
Run Code Online (Sandbox Code Playgroud)
或者在Swift中(与iOS 11中的Swift 4.1一起使用)
let fixedWidth = textView.frame.size.width
let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
textView.frame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
Run Code Online (Sandbox Code Playgroud)
如果您想要支持iOS 6.1,那么您还应该:
textview.scrollEnabled = NO;
Run Code Online (Sandbox Code Playgroud)
Ron*_*iew 576
实际上有一种非常简单的方法可以调整UITextView内容的正确高度.它可以使用UITextView contentSize.
CGRect frame = _textView.frame;
frame.size.height = _textView.contentSize.height;
_textView.frame = frame;
Run Code Online (Sandbox Code Playgroud)
有一点要注意的是,正确的contentSize是唯一可用后的UITextView已加入的观点addSubview.在此之前它等于frame.size
如果自动布局为ON,则无效.使用自动布局时,一般方法是使用该sizeThatFits方法并更新constant高度约束上的值.
CGSize sizeThatShouldFitTheContent = [_textView sizeThatFits:_textView.frame.size];
heightConstraint.constant = sizeThatShouldFitTheContent.height;
Run Code Online (Sandbox Code Playgroud)
heightConstraint 是您通常通过将属性链接到故事板中创建的高度约束来通过IBOutlet设置的布局约束.
只是为了增加这个惊人的答案,2014年,如果你:
[self.textView sizeToFit];
Run Code Online (Sandbox Code Playgroud)
仅与iPhone6 +的行为有所不同:

只有6+(不是5s或6),它确实为UITextView添加了"一个空行"."RL解决方案"完美地解决了这个问题:
CGRect _f = self.mainPostText.frame;
_f.size.height = self.mainPostText.contentSize.height;
self.mainPostText.frame = _f;
Run Code Online (Sandbox Code Playgroud)
它解决了6+以上的"额外线路"问题.
Bre*_*ald 90
为了UITextView在内部进行动态调整UITableViewCell,我发现以下组合在Xcode 6中与iOS 8 SDK一起使用:
UITextView到a UITableViewCell并将其约束到两侧UITextView的scrollEnabled属性NO.启用滚动后,其框架UITextView与其内容大小无关,但在禁用滚动的情况下,两者之间存在关系.如果您的表使用原始默认行高44,那么它将自动计算行高,但如果您将默认行高更改为其他行,则可能需要手动启用行高的自动计算viewDidLoad:
tableView.estimatedRowHeight = 150;
tableView.rowHeight = UITableViewAutomaticDimension;
Run Code Online (Sandbox Code Playgroud)对于只读的动态调整大小UITextView,就是这样.如果您允许用户编辑您的文本UITextView,您还需要:
实现协议的textViewDidChange:方法UITextViewDelegate,并告诉tableView每次编辑文本时重绘自己:
- (void)textViewDidChange:(UITextView *)textView;
{
[tableView beginUpdates];
[tableView endUpdates];
}
Run Code Online (Sandbox Code Playgroud)并且不要忘记UITextView将代理设置在某个地方,无论是在内部Storyboard还是内部tableView:cellForRowAtIndexPath:
Alo*_*lok 63
使用代码和故事板的非常简单的工作解决方案.
按代码
textView.scrollEnabled = false
Run Code Online (Sandbox Code Playgroud)
通过故事板
取消选中滚动启用
除此之外无需做任何事情.
Jua*_*ero 58
斯威夫特:
textView.sizeToFit()
Run Code Online (Sandbox Code Playgroud)
小智 24
在我(有限)的经历中,
- (CGSize)sizeWithFont:(UIFont *)font forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode
Run Code Online (Sandbox Code Playgroud)
不尊重换行符,因此最终可能CGSize比实际需要的要短很多.
- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size
Run Code Online (Sandbox Code Playgroud)
似乎确实尊重新线.
此外,文本实际上并未呈现在顶部UITextView.在我的代码中,我将新的高度设置为UITextView比sizeOfFont方法返回的高度大24个像素.
pha*_*ann 22
在iOS6中,您可以contentSize在设置文本后立即检查UITextView 的属性.在iOS7中,这将不再有效.如果要为iOS7恢复此行为,请将以下代码放在UITextView的子类中.
- (void)setText:(NSString *)text
{
[super setText:text];
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
CGRect rect = [self.textContainer.layoutManager usedRectForTextContainer:self.textContainer];
UIEdgeInsets inset = self.textContainerInset;
self.contentSize = UIEdgeInsetsInsetRect(rect, inset).size;
}
}
Run Code Online (Sandbox Code Playgroud)
Nik*_*ook 18
我将在页面底部发布正确的解决方案,以防有人勇敢(或绝望)阅读到这一点.
这里有gitHub repo,他们不想阅读所有文本:resizableTextView
这适用于iOs7(我相信它适用于iOs8)和自动布局.你不需要魔术数字,禁用布局和类似的东西.简洁优雅的解决方案.
我认为,所有与约束相关的代码都应该转向updateConstraints方法.所以,让我们自己做ResizableTextView.
我们在这里遇到的第一个问题是在viewDidLoad方法之前不知道真正的内容大小.我们可以采取漫长而错误的道路,并根据字体大小,换行符等计算它.但我们需要强大的解决方案,所以我们将做:
CGSize contentSize = [self sizeThatFits:CGSizeMake(self.frame.size.width, FLT_MAX)];
所以现在我们知道真实的contentSize,无论我们在哪里:之前或之后viewDidLoad.现在在textView上添加高度约束(通过故事板或代码,无论如何).我们将使用以下方式调整该值contentSize.height:
[self.constraints enumerateObjectsUsingBlock:^(NSLayoutConstraint *constraint, NSUInteger idx, BOOL *stop) {
if (constraint.firstAttribute == NSLayoutAttributeHeight) {
constraint.constant = contentSize.height;
*stop = YES;
}
}];
Run Code Online (Sandbox Code Playgroud)
最后要做的就是告诉超类updateConstraints.
[super updateConstraints];
Run Code Online (Sandbox Code Playgroud)
现在我们的班级看起来像:
ResizableTextView.m
- (void) updateConstraints {
CGSize contentSize = [self sizeThatFits:CGSizeMake(self.frame.size.width, FLT_MAX)];
[self.constraints enumerateObjectsUsingBlock:^(NSLayoutConstraint *constraint, NSUInteger idx, BOOL *stop) {
if (constraint.firstAttribute == NSLayoutAttributeHeight) {
constraint.constant = contentSize.height;
*stop = YES;
}
}];
[super updateConstraints];
}
Run Code Online (Sandbox Code Playgroud)
漂亮干净吧?而且您不必在控制器中处理该代码!
可是等等! 你没动画!
您可以轻松地动画更改以使textView拉伸顺利进行.这是一个例子:
[self.view layoutIfNeeded];
// do your own text change here.
self.infoTextView.text = [NSString stringWithFormat:@"%@, %@", self.infoTextView.text, self.infoTextView.text];
[self.infoTextView setNeedsUpdateConstraints];
[self.infoTextView updateConstraintsIfNeeded];
[UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionLayoutSubviews animations:^{
[self.view layoutIfNeeded];
} completion:nil];
Run Code Online (Sandbox Code Playgroud)
Mik*_*ter 12
你试过[textView sizeThatFits:textView.bounds]吗?
编辑:sizeThatFits返回大小但实际上并未调整组件大小.我不确定这是不是你想要的,或者是否[textView sizeToFit]更符合你的要求.在任何一种情况下,我都不知道它是否完全适合您想要的内容,但这是首先尝试的.
小智 9
另一种方法是使用以下NSString方法查找特定字符串将占用的大小:
-(CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size
这将返回适合给定字符串的矩形的大小.传递具有所需宽度和最大高度的大小,然后您可以查看返回的高度以适合文本.有一个版本可以让你指定换行模式.
然后,您可以使用返回的大小来更改视图的大小以适应.
如果您没有UITextView方便(例如,您正在调整表视图单元格),则必须通过测量字符串来计算大小,然后计算a的每一侧的8 pt填充UITextView.例如,如果您知道文本视图的所需宽度并想要计算出相应的高度:
NSString * string = ...;
CGFloat textViewWidth = ...;
UIFont * font = ...;
CGSize size = CGSizeMake(textViewWidth - 8 - 8, 100000);
size.height = [string sizeWithFont:font constrainedToSize:size].height + 8 + 8;
Run Code Online (Sandbox Code Playgroud)
这里,每个8占据了四个填充边缘之一,而100000只是一个非常大的最大尺寸.
在实践中,您可能想要font.leading在高度上添加额外的东西; 这会在文本下方添加一个空白行,如果文本视图正下方有视觉上很重的控件,则可能看起来更好.
我们可以通过约束来实现.
2.为该高度约束创建IBOutlet.
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *txtheightconstraints;
Run Code Online (Sandbox Code Playgroud)
3.不要忘记为你的textview设置委托.
4.
-(void)textViewDidChange:(UITextView *)textView
{
CGFloat fixedWidth = textView.frame.size.width;
CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
CGRect newFrame = textView.frame;
newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
NSLog(@"this is updating height%@",NSStringFromCGSize(newFrame.size));
[UIView animateWithDuration:0.2 animations:^{
_txtheightconstraints.constant=newFrame.size.height;
}];
}
Run Code Online (Sandbox Code Playgroud)
然后像这样更新你的约束:)
结合Mike McMaster的回答,您可能希望做以下事情:
[myTextView setDelegate: self];
...
- (void)textViewDidChange:(UITextView *)textView {
if (myTextView == textView) {
// it changed. Do resizing here.
}
}
Run Code Online (Sandbox Code Playgroud)
小智 6
我发现了一种根据文本字段内部文本调整文本字段高度的方法,并根据文本字段的高度在其下方排列标签!这是代码.
UITextView *_textView = [[UITextView alloc] initWithFrame:CGRectMake(10, 10, 300, 10)];
NSString *str = @"This is a test text view to check the auto increment of height of a text view. This is only a test. The real data is something different.";
_textView.text = str;
[self.view addSubview:_textView];
CGRect frame = _textView.frame;
frame.size.height = _textView.contentSize.height;
_textView.frame = frame;
UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(10, 5 + frame.origin.y + frame.size.height, 300, 20)];
lbl.text = @"Hello!";
[self.view addSubview:lbl];
Run Code Online (Sandbox Code Playgroud)
使用自动布局和你的sizetofit的人不起作用,请检查你的宽度约束一次.如果您错过了宽度约束,那么高度将是准确的.
无需使用任何其他API.只需一行即可解决所有问题.
[_textView sizeToFit];
Run Code Online (Sandbox Code Playgroud)
在这里,我只关心高度,保持宽度固定,并错过了我的TextView在故事板中的宽度约束.
这是为了显示来自服务的动态内容.
希望这可能有所帮助..
从iOS 8开始,可以使用UITableView的自动布局功能自动调整UITextView的大小,而根本不需要自定义代码.我已经在github上放了一个项目来演示这个,但是关键是:
rowHeight为UITableViewAutomaticDimension.
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.estimatedRowHeight = self.tableView.rowHeight;
self.tableView.rowHeight = UITableViewAutomaticDimension;
}
Run Code Online (Sandbox Code Playgroud)
我查看了所有答案,所有答案均保持固定宽度,仅调整高度。如果您还希望调整宽度,则可以很容易地使用此方法:
因此在配置文本视图时,请禁用滚动
textView.isScrollEnabled = false
Run Code Online (Sandbox Code Playgroud)
然后在委托方法中func textViewDidChange(_ textView: UITextView)添加以下代码:
func textViewDidChange(_ textView: UITextView) {
let newSize = textView.sizeThatFits(CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude))
textView.frame = CGRect(origin: textView.frame.origin, size: newSize)
}
Run Code Online (Sandbox Code Playgroud)
输出:
禁用滚动
添加约束
并添加您的文字
[yourTextView setText:@"your text"];
[yourTextView layoutIfNeeded];
Run Code Online (Sandbox Code Playgroud)
如果你使用,UIScrollView你也应该添加这个;
[yourScrollView layoutIfNeeded];
-(void)viewDidAppear:(BOOL)animated{
CGRect contentRect = CGRectZero;
for (UIView *view in self.yourScrollView.subviews) {
contentRect = CGRectUnion(contentRect, view.frame);
}
self.yourScrollView.contentSize = contentRect.size;
}
Run Code Online (Sandbox Code Playgroud)
小智 5
使用 UITextViewDelegate 是最简单的方法:
func textViewDidChange(_ textView: UITextView) {
textView.sizeToFit()
textviewHeight.constant = textView.contentSize.height
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
365089 次 |
| 最近记录: |