IT

텍스트 길이에 따라 UITextView 높이를 동적으로 설정하는 방법은 무엇입니까?

itgroup 2023. 8. 31. 23:49
반응형

텍스트 길이에 따라 UITextView 높이를 동적으로 설정하는 방법은 무엇입니까?

이 이미지에서 볼 수 있듯이

그자리의 UITextView텍스트 길이에 따라 높이가 변경됩니다. 텍스트 길이에 따라 높이를 조정하고 싶습니다.

*다른 질문을 보았지만 솔루션이 제대로 작동하지 않았습니다.

example

이것은 저에게 효과가 있지만, 다른 모든 솔루션은 그렇지 않았습니다.

func adjustUITextViewHeight(arg : UITextView) {
    arg.translatesAutoresizingMaskIntoConstraints = true
    arg.sizeToFit()
    arg.scrollEnabled = false
}

에서는 Swift 4의 을 사용합니다.arg.scrollEnabled = false이 변었습니다되경으로 변경되었습니다.arg.isScrollEnabled = false.

Storyboard / Interface Builder에서는 속성 검사기에서 스크롤을 비활성화하기만 하면 됩니다.

드로에서textField.scrollEnabled = false그 묘기를 부려야 합니다.

내가 해야 할 일은:

  1. 텍스트 보기의 맨 위, 왼쪽오른쪽에 구속조건을 설정합니다.
  2. 스토리보드에서 스크롤을 사용할 수 없습니다.

이렇게 하면 자동 레이아웃을 사용하여 내용에 따라 텍스트 보기의 크기를 동적으로 조정할 수 있습니다.

시도해 보십시오.

CGRect frame = self.textView.frame;
frame.size.height = self.textView.contentSize.height;
self.textView.frame = frame;

편집 - 스위프트가 있습니다.

var frame = self.textView.frame
frame.size.height = self.textView.contentSize.height
self.textView.frame = frame

스위프트 4

클래스에 추가

UITextViewDelegate

func textViewDidChange(_ textView: UITextView) {
      let fixedWidth = textView.frame.size.width
      textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
      let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
      var newFrame = textView.frame
      newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
      textView.frame = newFrame
}

데야 엘딘의 대답이 뒤를 이었습니다.
저 같은 경우에는.다음을 추가하여 텍스트 보기 높이를 자동으로 높입니다.

swift 3

textView.translatesAutoresizingMaskIntoConstraints = false textView.isScrollEnabled = false

스위프트 5, 확장 사용:

extension UITextView {
    func adjustUITextViewHeight() {
        self.translatesAutoresizingMaskIntoConstraints = true
        self.sizeToFit()
        self.isScrollEnabled = false
    }
}

사용 사례:

textView.adjustUITextViewHeight()

그리고 스토리보드에서 texteView의 높이는 상관하지 않습니다(처음에는 상수만 사용).

텍스트와 연결만 하면 됩니다. 높이 제약 조건 보기

@IBOutlet var textView: UITextView!
@IBOutlet var textViewHeightConstraint: NSLayoutConstraint!

그리고 아래의 코드를 사용합니다.

textViewHeightConstraint.constant = self.textView.contentSize.height

만약 당신이textView콘텐츠만큼 성장할 수 있도록 허용됩니다.

textView.isScrollEnabled = false

자동 레이아웃과 함께 작동해야 합니다.

만약 당신이 남아 있고 싶다면.textView하려면 선택적인 을 추가해야 .

internal lazy var textViewHeightConstraint: NSLayoutConstraint = {
  let constraint = self.textView.heightAnchor.constraint(equalToConstant: 0)
  constraint.priority = .defaultHigh
  return constraint
}()

public override func layoutSubviews() {
  super.layoutSubviews()

  // Assuming there is width constraint setup on the textView.
  let targetSize = CGSize(width: textView.frame.width, height: CGFloat(MAXFLOAT))
  textViewHeightConstraint.constant = textView.sizeThatFits(targetSize).height
}

를 재정의하는 layoutSubviews()너비에 따라 높이를 계산할 수 있도록 textView가 수평으로 올바르게 배치되었는지 확인합니다.

높이 제약 조건이 낮은 우선순위로 설정되어 있기 때문에 수직으로 공간이 부족할 경우 실제 높이는textView 을것니다입보다 입니다.contentSize그러면 텍스트 보기를 스크롤할 수 있습니다.

나는 이 두 줄의 코드를 추가했고 나에게 잘 작동합니다.

Swift 5+에서 작동합니다.

func adjustUITextViewHeight(textView : UITextView)
{
     textView.translatesAutoresizingMaskIntoConstraints = true
     textView.isScrollEnabled = false
     textView.sizeToFit()
}

이 답변이 늦을지도 모르지만 누군가에게 도움이 되었으면 좋겠습니다.

제게는 다음 두 줄의 코드가 작동했습니다.

textView.isScrollEnabled = false
textView.sizeToFit()

그러나 텍스트 보기에 대한 높이 제한을 설정하지 마십시오.

프로그래밍 방식으로 하는 것은 간단합니다. 다음 단계를 따르십시오.

  1. 텍스트 필드의 내용 길이에 관찰자 추가

    [yourTextViewObject addObserver:self forKeyPath:@"contentSize" options:(NSKeyValueObservingOptionNew) context:NULL];
    
  2. 관찰자를 실행합니다.

    -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    UITextView *tv = object;
    
        //Center vertical alignment
        CGFloat topCorrect = ([tv bounds].size.height - [tv contentSize].height * [tv zoomScale])/2.0;
        topCorrect = ( topCorrect < 0.0 ? 0.0 : topCorrect );
        tv.contentOffset = (CGPoint){.x = 0, .y = -topCorrect};
    
    
        mTextViewHeightConstraint.constant = tv.contentSize.height;
    
        [UIView animateWithDuration:0.2 animations:^{
    
            [self.view layoutIfNeeded];
        }];
    
    }
    
  3. 텍스트 보기를 중지하려면입력하는 동안 시간이 지나면 증가할 높이를 설정한 다음 이를 구현하고 텍스트 보기 대리자를 자체로 설정합니다.

    -(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
    {
        if(range.length + range.location > textView.text.length)
        {
            return NO;
        }
    
        NSUInteger newLength = [textView.text length] + [text length] - range.length;
    
        return (newLength > 100) ? NO : YES;
    
    }
    

스위프트 4+

이것은 자동 레이아웃으로 매우 쉽습니다!가장 간단한 사용 사례를 설명하겠습니다.예를 들어 다음과 같은 경우가 있습니다.UITextView당신의UITableViewCell.

  • 맞춤textView에게contentView제약을 부려
  • 에 대해 스크롤 사용 안 함textView.
  • 업데이트tableViewtextViewDidChange.

그게 다야!

protocol TextViewUpdateProtocol {
    func textViewChanged()
}

class TextViewCell: UITableViewCell {
    
    //MARK: Reuse ID
    static let identifier = debugDescription()
    
    //MARK: UI Element(s)
    /// Reference of the parent table view so that it can be updated
    var textViewUpdateDelegate: TextViewUpdateProtocol!
    
    lazy var textView: UITextView = {
        let textView = UITextView()
        textView.isScrollEnabled = false
        textView.delegate = self
        textView.layer.borderColor = UIColor.lightGray.cgColor
        textView.layer.borderWidth = 1
        textView.translatesAutoresizingMaskIntoConstraints = false
        return textView
    }()
    
    //MARK: Padding Variable(s)
    let padding: CGFloat = 50
    
    //MARK: Initializer(s)
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        addSubviews()
        addConstraints()
        
        textView.becomeFirstResponder()
    }
    
    //MARK: Helper Method(s)
    func addSubviews() {
        contentView.addSubview(textView)
    }
    
    func addConstraints() {
        textView.leadingAnchor  .constraint(equalTo: contentView.leadingAnchor, constant: padding).isActive = true
        textView.trailingAnchor .constraint(equalTo: contentView.trailingAnchor, constant: -padding).isActive = true
        textView.topAnchor      .constraint(equalTo: contentView.topAnchor, constant: padding).isActive = true
        textView.bottomAnchor   .constraint(equalTo: contentView.bottomAnchor, constant: -padding).isActive = true
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
}

extension TextViewCell: UITextViewDelegate {
    
    func textViewDidChange(_ textView: UITextView) {
        textViewUpdateDelegate.textViewChanged()
    }
    
}

이제 프로토콜 구현을 상속해야 합니다.ViewController.

extension ViewController: TextViewUpdateProtocol {
    
    func textViewChanged() {
        tableView.beginUpdates()
        tableView.endUpdates()
    }
    
}

전체 구현에 대한 내 보고서를 확인하십시오.

스위프트 4

입력할 때 크기 변경

UI 텍스트 보기 대표자

func textViewDidChange(_ textView: UITextView) {
        yourTextView.translatesAutoresizingMaskIntoConstraints = true
        yourTextView.sizeToFit()
        yourTextView.isScrollEnabled = false

        let calHeight = yourTextView.frame.size.height
        yourTextView.frame = CGRect(x: 16, y: 193, width: self.view.frame.size.width - 32, height: calHeight)
    }

로드 시 크기 변경

func textViewNotasChange(arg : UITextView) {
        arg.translatesAutoresizingMaskIntoConstraints = true
        arg.sizeToFit()
        arg.isScrollEnabled = false

        let calHeight = arg.frame.size.height
        arg.frame = CGRect(x: 16, y: 40, width: self.view.frame.size.width - 32, height: calHeight)
    }

두 번째 옵션의 기능을 다음과 같이 호출합니다.

textViewNotasChange(arg: yourTextView)

제 프로젝트에서 뷰 컨트롤러는 많은 제약 조건과 StackView와 관련되어 있으며, TextView 높이를 제약 조건으로 설정했는데 textView.contentSize에 따라 달라집니다.높이 값

1단계: IB 아웃렛 확보

@IBOutlet weak var textViewHeight: NSLayoutConstraint!

2단계: 아래 위임 방법을 사용합니다.

extension NewPostViewController: UITextViewDelegate {
     func textViewDidChange(_ textView: UITextView) {
          textViewHeight.constant = self.textView.contentSize.height + 10
     }
}

낫지만 빠른 4를 확장으로 추가합니다.

extension UITextView {
    func resizeForHeight(){
        self.translatesAutoresizingMaskIntoConstraints = true
        self.sizeToFit()
        self.isScrollEnabled = false
    }
}

효과가 있는

func textViewDidChange(_ textView: UITextView) {
    let fixedWidth = textviewconclusion.frame.size.width
    textviewconclusion.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
    let newSize = textviewconclusion.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
    var newFrame = textviewconclusion.frame
    newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
    textviewconclusion.frame = newFrame
}

1 텍스트 필드의 내용 길이에 관찰자 추가

   yourTextView.addObserver(self, forKeyPath: "contentSize", options: (NSKeyValueObservingOptions.new), context: nil);

2 관찰자 구현

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        let tv = object as! UITextView;
        var topCorrect = (tv.bounds.size.height - tv.contentSize.height * tv.zoomScale)/2.0;
        topCorrect = ( topCorrect < 0.0 ? 0.0 : topCorrect );
        tv.contentOffset.x = 0;
        tv.contentOffset.y = -topCorrect;
        self.yourTextView.contentSize.height = tv.contentSize.height;
        UIView.animate(withDuration: 0.2, animations: {
            self.view.layoutIfNeeded();
        });
    }

다음은 iOS 8.3의 두 가지 함정입니다.textView.textContainer.maximumNumberOfLines = 10

요점을 참조해 주세요.

textView.attributedText = originalContent

let lineLimit = 10
textView.isEditable = true
textView.isScrollEnabled = false
textView.textContainerInset = .zero // default is (8, 0, 8, 0)
textView.textContainer.maximumNumberOfLines = lineLimit // Important condition
textView.textContainer.lineBreakMode = .byTruncatingTail

// two incomplete methods, which do NOT work in iOS 8.3

// size.width可能比maxSize.width小 ————遗憾的是 iOS 8.3 上此方法无视maximumNumberOfLines参数,所以得借助于UILabel
// size.width may be less than maxSize.width, ---- Do NOT work in iOS 8.3, which disregards textView.textContainer.maximumNumberOfLines
// let size = textView.sizeThatFits(maxSize) 

// 遗憾的是 iOS 8.3 上此方法失效了,得借助于UILabel
// Does not work in iOS 8.3
// let size = textView.layoutManager.usedRectForTextContainer(textView.textContainer).size 

// Suggested method: use a temperary label to get its size
let label = UILabel(); label.attributedText = originalContent
let size = label.textRect(forBounds: CGRect(origin: .zero, size: maxSize), limitedToNumberOfLines: lineLimit).size
textView.frame.size = size

여기서 선언

    fileprivate weak var textView: UITextView!

설정 보기를 여기로 호출

    override func viewDidLoad() {
        super.viewDidLoad()

         setupViews()
    }

여기서 설정

    fileprivate func setupViews() {

    let textView = UITextView()
    textView.translatesAutoresizingMaskIntoConstraints = false
    textView.text = "your text here"
    textView.font = UIFont.poppinsMedium(size: 14)
    textView.textColor = UIColor.brownishGrey
    textView.textAlignment = .left
    textView.isEditable = false
    textView.isScrollEnabled = false
    textView.textContainerInset = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20)

   self.view.addSubview(textView)

   self.textView = textView

   setupConstraints()

   }

여기에 제약 조건 설정

   fileprivate func setupConstraints() {

    NSLayoutConstraint.activate([

        textView.topAnchor.constraint(equalTo: view.topAnchor, constant: 20),
        textView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20),
        textView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -20),
        textView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -20),
        textView.heightAnchor.constraint(greaterThanOrEqualToConstant: 150),
        ])
  }

메시지 앱에서와 같이 내부 콘텐츠 크기에 따라 텍스트 보기의 크기를 조정해야 할 때마다코코팟(GrowingTextView)을 사용하면 텍스트 보기의 동적 크기 조정을 직접 코딩하는 것보다 삶을 더 쉽게 만들 수 있습니다.

  1. 스택 뷰에 텍스트 뷰 삽입
  2. stackView에 대한 제약 조건(위, 아래, 왼쪽, 오른쪽) 설정
  3. StackView에 높이 제약 조건을 추가하고 이 제약 조건을 선택한 후 오른쪽 패널의 Relation에서 'Greater Than or Equal'로 설정합니다.

프리로드를 원하시면textView컨트롤러 로드에서.뷰에서 이 함수 호출didload():

func textViewDidChange(_ textView: UITextView) {   
    let esmitated = CGSize(width: txtView.frame.width, height: .infinity)
    let esmitatedSize = txtView.sizeThatFits(esmitated)
    self.heghtConstraint.constant = esmitatedSize.height
}

언급URL : https://stackoverflow.com/questions/38714272/how-to-make-uitextview-height-dynamic-according-to-text-length

반응형