我有一个TextView,其最小高度为33.从故事板中禁用滚动。 TextView应根据内容增加高度,直到达到100的最大高度。然后我将scrollEnabled更改为true,将TextView的高度更改为最大高度100,但高度更改为33.如何修复这个问题?
import UIKit
class ViewController: UIViewController, UITextViewDelegate {
@IBOutlet weak var messageTextView: UITextView!
let messageTextViewMaxHeight: CGFloat = 100
override func viewDidLoad() {
super.viewDidLoad()
self.messageTextView.delegate = self
}
func textViewDidChange(textView: UITextView) {
if textView.frame.size.height >= self.messageTextViewMaxHeight {
textView.scrollEnabled = true
textView.frame.size.height = self.messageTextViewMaxHeight
} else {
textView.scrollEnabled = false
}
}
}
答案 0 :(得分:6)
您的代码似乎需要进行两项更改,并且可以正常运行。
更改代码如下:
import UIKit
class ViewController: UIViewController, UITextViewDelegate
{
@IBOutlet weak var messageTextView: UITextView!
let messageTextViewMaxHeight: CGFloat = 100
override func viewDidLoad()
{
super.viewDidLoad()
messageTextView.delegate = self
}
func textViewDidChange(textView: UITextView)
{
if textView.contentSize.height >= self.messageTextViewMaxHeight
{
textView.scrollEnabled = true
}
else
{
textView.frame.size.height = textView.contentSize.height
textView.scrollEnabled = false // textView.isScrollEnabled = false for swift 4.0
}
}
}
答案 1 :(得分:1)
这采用了相似的方法来处理已接受的答案,但要确保textView
在两个高度状态下都完全受约束。
(接受的答案中有一个错误-在启用滚动功能时,使用具有<=
关系的高度约束不足以完全约束textView
,因为在这种情况下,视图不提供{{ 1}}。您可以在IB中(禁用滚动功能)或在运行时通过视图调试看到它。)
这是必需的:
intrinsicContentSize
无需手动设置框架,因为在这两种情况下都可以使用自动布局。
答案 2 :(得分:0)
解决问题的简单方法是在textViewDidChange调用时更改textView的框架。 UITextView实际上是一个UIScrollView。如果必须使用约束,则必须更改约束的常量。 这是我的代码:
import UIKit
let width = UIScreen.mainScreen().bounds.width
class ViewController: UIViewController, UITextViewDelegate {
var messageTextView: UITextView!
let messageTextViewMaxHeight: CGFloat = 100
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.redColor()
messageTextView = UITextView(frame: CGRectMake(0, 200 - 33, width, 33))
messageTextView.backgroundColor = UIColor.whiteColor()
view.addSubview(messageTextView)
self.messageTextView.delegate = self
}
//
let bottomY: CGFloat = 200
func textViewDidChange(textView: UITextView) {
let formerRect = textView.frame
if formerRect.height > messageTextViewMaxHeight{
}
else{
textView.frame = CGRectMake(formerRect.origin.x, bottomY - textView.contentSize.height, width, textView.contentSize.height)
}
}
}
答案 3 :(得分:0)
也许下面的代码更好一点。
import UIKit
let width = UIScreen.mainScreen().bounds.width
class ViewController: UIViewController, UITextViewDelegate {
var messageTextView: UITextView!
let messageTextViewMaxHeight: CGFloat = 100
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.redColor()
messageTextView = UITextView(frame: CGRectMake(0, 200 - 33, width, 33))
messageTextView.backgroundColor = UIColor.whiteColor()
view.addSubview(messageTextView)
self.messageTextView.delegate = self
}
//
let bottomY: CGFloat = 200
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
if text == "\n"{
let formerRect = textView.frame
let contentSize = textView.contentSize
if contentSize.height < formerRect.height{
//
}
else{
if contentSize.height >= messageTextViewMaxHeight{
//
}
else{
textView.frame = CGRectMake(formerRect.origin.x, bottomY - contentSize.height, width, contentSize.height)
}
}
}
return true
}
}
答案 4 :(得分:0)
在表格视图单元格中查看了很多小时的文本视图问题后,这个解决方案对我有用。我正在使用Masonry,但也可以在IB中创建约束。
请注意,textview委托是不使用。这是有利的,因为无论是以编程方式还是通过用户输入更改文本都无关紧要。无论哪种方式,只要文本视图更改其内容,就会调用layoutSubviews。
如果您想直接在视图控制器中使用此功能,可以使用viewDidLayoutSubviews
代替layoutSubviews
。
@implementation TextViewCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self){
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectZero];
textView.scrollEnabled = NO;
self.textView = textView;
[self.contentView addSubview:self.textView];
[self.textView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.leading.equalTo(self.contentView.mas_leadingMargin);
make.trailing.equalTo(self.contentView.mas_trailingMargin);
make.top.equalTo(self.contentView.mas_topMargin);
make.bottom.equalTo(self.contentView.mas_bottomMargin);
make.height.lessThanOrEqualTo(@100.0).with.priorityHigh();
make.height.greaterThanOrEqualTo(@30.0).with.priorityHigh();
}];
}
return self;
}
- (void)layoutSubviews{
CGSize size = [self.textView sizeThatFits:CGSizeMake(self.textView.bounds.size.width, 10000)];
self.textView.scrollEnabled = size.height > 100.0;
[super layoutSubviews];
}
@end
答案 5 :(得分:0)
创建一个继承自UITextView的类,并将以下内容添加到该类中:
class CustomTextView: UITextView, UITextViewDelegate {
override init(frame: CGRect, textContainer: NSTextContainer?) {
super.init(frame: frame, textContainer: textContainer)
delegate = self
}
var maxHeight: CGFloat = 200
override var intrinsicContentSize: CGSize {
var size = super.intrinsicContentSize
if size.height > maxHeight {
size.height = maxHeight
isScrollEnabled = true
} else {
isScrollEnabled = false
}
return size
}
override var text: String! {
didSet {
invalidateIntrinsicContentSize()
}
}
func textViewDidChange(_ textView: UITextView) {
invalidateIntrinsicContentSize()
}
}
注意: -创建CustomTextView之后,可以将maxHeight初始化为无穷大并设置maxHeight。此类可以在应用程序中需要的任何地方重复使用,并且可以针对不同的情况修改最大高度。
答案 6 :(得分:0)
我的解决方案是,在CostumeView上,我向UITextView添加了约束:
textInput.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
textInput.topAnchor.constraint(equalTo: divider.bottomAnchor, constant: 5),
textInput.heightAnchor.constraint(lessThanOrEqualToConstant: 100), // very important
textInput.leadingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leadingAnchor),
textInput.bottomAnchor.constraint(equalTo: self.safeAreaLayoutGuide.bottomAnchor)])
“ textInput.heightAnchor.constraint(lessThanOrEqualToConstant:100)”就是它的窍门。 因此,我将UITextView设置为isScrollEnabled = false:
textView.isScrollEnabled = false
然后在ViewController上添加UITextViewDelegate:
extension InboxMsgVC: UITextViewDelegate {
最后我添加了以下方法:
func textViewDidChange(_ textView: UITextView) {
if textView.contentSize.height >= 100 {
textView.isScrollEnabled = true
} else {
textView.isScrollEnabled = false
}
}
是的,它对我来说很好,Swift 5。