[ios] UITextView에서 여백 / 패딩을 잃는 방법?

나는이 UITextView많은 양의 텍스트를 표시 내 아이폰 OS 응용 프로그램에서.

그런 다음의 오프셋 여백 매개 변수를 사용 하여이 텍스트를 페이징합니다 UITextView.

내 문제는 사용하는 UITextView글꼴 크기와 서체에 따라 다르게 보이는 것처럼 패딩이 계산을 혼란스럽게한다는 것입니다.

따라서 나는 다음과 같은 질문을 제기합니다 :의 내용을 둘러싼 패딩을 제거 할 수 UITextView있습니까?

답변을 기다리겠습니다!



답변

2019 년 최신

iOS에서 가장 심각한 버그 중 하나입니다.

여기에 주어진 수업 UITextViewFixed은 일반적으로 가장 합리적인 솔루션입니다.

수업은 다음과 같습니다.

@IBDesignable class UITextViewFixed: UITextView {
    override func layoutSubviews() {
        super.layoutSubviews()
        setup()
    }
    func setup() {
        textContainerInset = UIEdgeInsets.zero
        textContainer.lineFragmentPadding = 0
    }
}

인스펙터에서 scrollEnabled를 끄는 것을 잊지 마십시오!

  1. 솔루션은 스토리 보드에서 올바르게 작동합니다

  2. 솔루션은 런타임에 올바르게 작동합니다

그게 다야, 끝났어.

일반적으로 대부분의 경우 필요한 것입니다 .

텍스트보기의 높이를 즉석 에서 변경하더라도 UITextViewFixed일반적으로 필요한 모든 것을 수행합니다.

(즉석에서 높이를 변경하는 일반적인 예는 사용자 유형에 따라 높이를 변경하는 것입니다.)

Apple에서 깨진 UITextView는 다음과 같습니다.

UITextView가있는 IB 스크린 샷

여기 있습니다 UITextViewFixed:

UITextViewFixed를 사용한 IB 스크린 샷

물론 당신은해야합니다

인스펙터에서 scrollEnabled를 끄십시오!

scrollEnabled를 끄는 것을 잊지 마십시오! 🙂


몇 가지 추가 문제

(1) 유동적이면서 동적으로 변화하는 셀 높이를 가진 테이블의 경우와 같은 비정상적인 경우 애플은 기괴한 일을한다. 그들은 바닥에 여분의 공간을 추가한다 . 아냐! 이것은 iOS에서 가장 분노한 것들 중 하나 여야합니다.

위의 내용에 추가 할 수있는 “빠른 수정 사항”은 일반적으로 그 광기에 도움이됩니다.

...
        textContainerInset = UIEdgeInsets.zero
        textContainer.lineFragmentPadding = 0

        // this is not ideal, but you can sometimes use this
        // to fix the "extra space at the bottom" insanity
        var b = bounds
        let h = sizeThatFits(CGSize(
           width: bounds.size.width,
           height: CGFloat.greatestFiniteMagnitude)
       ).height
       b.size.height = h
       bounds = b
 ...

(2) 때로는 또 다른 미묘한 Apple 엉망을 해결하려면 다음을 추가해야합니다.

override func setContentOffset(_ contentOffset: CGPoint, animated: Bool) {
    super.setContentOffset(contentOffset, animated: false)
}

(3) 틀림없이 다음을 추가 해야 합니다.

contentInset = UIEdgeInsets.zero

에서 직후 .lineFragmentPadding = 0UITextViewFixed.

그러나 … 믿거 나 말거나 … 현재 iOS 에서는 작동하지 않습니다 ! (2019 년에 확인 됨) 향후 해당 라인을 추가해야 할 수도 있습니다.

UITextViewiOS에서 깨어진 사실 은 모든 모바일 컴퓨팅에서 가장 이상한 것 중 하나입니다. 이 질문의 10 년 기념일은 여전히 ​​고정되어 있지 않습니다!

마지막으로, 텍스트 필드 와 비슷한 팁이 있습니다 : https://stackoverflow.com/a/43099816/294884

완전히 임의의 팁 : 끝에 “…”를 추가하는 방법

종종 “UILabel과 같은”UITextView를 사용하고 있습니다. 따라서 줄임표 “…”를 사용하여 텍스트를 자르기를 원합니다.

그렇다면 “setup”에 세 번째 코드 줄을 추가하십시오.

 textContainer.lineBreakMode = .byTruncatingTail

텍스트가 없을 때 높이가 0 인 경우 유용한 팁

텍스트보기를 사용하여 텍스트 만 표시하는 경우가 종종 있습니다. 따라서 사용자는 실제로 아무것도 편집 할 수 없습니다. “0”줄을 사용하면 텍스트 줄 수에 따라 텍스트보기의 높이가 자동으로 변경됩니다.

대단하지만, 텍스트가 전혀 없다면 불행히도 한 줄의 텍스트가 있는 것과 같은 높이를 얻습니다 !! 텍스트 뷰는 절대로 사라지지 않습니다.

여기에 이미지 설명을 입력하십시오

“가져 가기”를 원한다면, 이것을 추가하십시오

override var intrinsicContentSize: CGSize {
    var i = super.intrinsicContentSize
    print("for \(text) size will be \(i)")
    if text == "" { i.height = 1.0 }
    print("   but we changed it to \(i)")
    return i
}

여기에 이미지 설명을 입력하십시오

(나는 그것을 ‘1’로 만들었으므로 무슨 일이 일어나고 있는지, ‘0’은 괜찮습니다.)

UILabel은 어떻습니까?

텍스트를 표시 할 때 UILabel은 UITextView보다 많은 장점이 있습니다. UILabel은이 QA 페이지에 설명 된 문제를 겪지 않습니다. 실제로 우리 모두가 일반적으로 “포기”하고 UITextView를 사용하는 이유는 UILabel을 다루기가 어렵 기 때문입니다. 특히 UILabel에 padding 을 올바르게 추가하는 것은 엄청나게 어렵습니다 . 여기 사실 “마지막으로”제대로 UILabel의 패딩을 추가하는 방법에 대한 전체 설명이다 https://stackoverflow.com/a/58876988/294884 동적 높이 세포 어려운 레이아웃을하고 있다면 어떤 경우에는, 그것은 때때로 UILabel로 힘들게하는 것이 좋습니다.


답변

iOS 7.0의 경우 contentInset 트릭이 더 이상 작동하지 않는 것으로 나타났습니다. 이것은 iOS 7에서 여백 / 패딩을 제거하는 데 사용한 코드입니다.

이것은 텍스트의 왼쪽 가장자리를 컨테이너의 왼쪽 가장자리로 가져옵니다.

textView.textContainer.lineFragmentPadding = 0

이로 인해 텍스트 상단이 컨테이너 상단과 정렬됩니다.

textView.textContainerInset = .zero

여백 / 패딩을 완전히 제거하려면 두 줄이 모두 필요합니다.


답변

이 대안은 2009 년 IOS 3.0이 출시되었을 때 작성되었습니다. 더 이상 적용되지 않습니다.

나는 똑같은 문제에 부딪쳤다. 결국 나는

nameField.contentInset = UIEdgeInsetsMake(-4,-8,0,0);

여기서 nameField는입니다 UITextView. 내가 사용했던 글꼴은 Helvetica 16 포인트였습니다. 내가 그리는 특정 필드 크기에 대한 맞춤형 솔루션 만입니다. 이렇게하면 왼쪽 오프셋이 왼쪽과 플러시되고 상자에 대한 상단 오프셋이 그려집니다.

또한 UITextViews기본 계약을 사용하는 경우 에만 적용됩니다 .

nameField.textAlignment = NSTextAlignmentLeft;

예를 들어 오른쪽에 맞추면 UIEdgeInsetsMake오른쪽 가장자리에 전혀 영향을 미치지 않는 것 같습니다.

최소한 .contentInset 속성을 사용하면 필드를 “올바른”위치에 배치하고을 오프셋하지 않고 편차를 수용 할 수 있습니다 UITextViews.


답변

이미 제공된 좋은 답변 중 일부를 작성하면 iOS 7.0 이상에서 작동하는 순수한 스토리 보드 / 인터페이스 빌더 기반 솔루션이 있습니다.

다음 키에 대해 UITextView의 사용자 정의 런타임 속성 을 설정하십시오 .

textContainer.lineFragmentPadding
textContainerInset

인터페이스 빌더


답변

iOS 5에서는 UIEdgeInsetsMake(-8,-8,-8,-8);훌륭하게 작동합니다.


답변

실제 여백은 사용자 글꼴 크기 설정 등에 따라 변경 될 수 있으므로 하드 코딩 된 값과 관련된 답변을 피할 수 있습니다.

여기에 @ user1687195의 답변이 있습니다 textContainer.lineFragmentPadding( 문서 상태가 의도 된 사용법이 아니기 때문에 ).

이것은 iOS 7 이상에서 효과적입니다.

self.textView.textContainerInset = UIEdgeInsetsMake(
                                      0,
                                      -self.textView.textContainer.lineFragmentPadding,
                                      0,
                                      -self.textView.textContainer.lineFragmentPadding);

이것은 사실상 동일한 결과이며 lineFragmentPadding 속성을 오용하지 않는다는 점에서 조금 더 깔끔합니다.


답변

사용자 정의 런타임 속성을 사용하는 스토리 보드 또는 인터페이스 빌더 솔루션 :

스크린 샷은 iOS 7.1 및 iOS 6.1의입니다 contentInset = {{-10, -5}, {0, 0}}.

사용자 정의 런타임 속성

산출