programing

UITextView에서의 마진/패딩 손실 방법

cafebook 2023. 4. 23. 11:27
반응형

UITextView에서의 마진/패딩 손실 방법

는 나나 a a a가 있다UITextView많은 양의 텍스트를 표시하는 iOS 어플리케이션에서 사용할 수 있습니다.

다음 이 를 '먹다'의 . 오프셋 여백 매개 변수를 사용하여UITextView.

는 제 of의 UITextView사용하는 글꼴 크기와 서체에 따라 다른 것 같아서 계산이 혼란스럽습니다.

의 내용을 할 수 ?UITextView

iOS 7.0의 경우 콘텐츠는인셋 트릭은 더 이상 작동하지 않습니다.iOS7에서 여백/패딩을 없애기 위해 사용한 코드입니다.

이렇게 하면 텍스트의 왼쪽 가장자리가 용기의 왼쪽 가장자리로 이동합니다.

textView.textContainer.lineFragmentPadding = 0

이렇게 하면 텍스트의 상단이 용기의 상단과 정렬됩니다.

textView.textContainerInset = .zero

여백/패드를 완전히 제거하려면 두 선이 모두 필요합니다.

2023년 최신 정보

iOS에서 가장 멍청한 버그 중 하나입니다.

, 기서는 the the the the 。UITextViewFixed는 널리 사용되며 일반적으로 가장 합리적인 솔루션입니다.

클래스는 다음과 같습니다.

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

Inspector에서 scrollEnabled를 해제하는 것을 잊지 마십시오!

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

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

모든 작업이 완료됩니다.일반적으로 필요한 것은 이것뿐입니다.

텍스트 뷰의 높이를 빠르게 변경하는 경우에도UITextViewFixed보통 필요한 건 다 해 주죠.

(높이를 온더플라이로 변경하는 일반적인 예는 사용자 유형에 따라 높이를 변경하는 것입니다.)

여기 Apple에서 고장난 UITextView가 있습니다.

UITextView를 사용한 Interface Builder 스크린샷

있습니다.UITextViewFixed:

UITextView를 사용한 Interface Builder 스크린샷

물론 당신은...

...Inspector에서 scrollEnabled를 해제합니다!

(scroll Enabled를 켜면 "하단 여백을 최대한 확장하여 이 보기를 최대한 수직으로 확장합니다.")


기타 문제

(1) 높이를 동적으로 변경할 때 매우 이례적인 경우, 애플은 하부에 추가 공간을 추가하는 이상한 일을 합니다.

아니, 정말이야!이것은 iOS에서 가장 짜증나는 것 중 하나일 것입니다.

문제가 발생했을 경우는, 다음의 「퀵 픽스」를 참조해 주세요.

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

        // this is not ideal, but sometimes this "quick fix"
        // will solve 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) // sic
}

(3) 다음과 같은 사항을 추가해야 합니다.

contentInset = UIEdgeInsets.zero

후직 .lineFragmentPadding = 0UITextViewFixed.

하지만 믿거나 말거나 현재 iOS에서는 작동하지 않습니다! (2023년 확인)향후 그 행을 추가할 필요가 있을지도 모릅니다.

UITextView에서 가장 것 중 입니다.OS는 모든 모바일 컴퓨팅에서 가장 이상한 것 중 하나입니다.이 질문의 10주년 기념일인데도 아직 해결되지 않았어요!

마지막으로 TextField에 대한 힌트: Swift에서 UITextField의 최대 문자 길이를 설정합니다.

완전 랜덤 팁: 끝에 "..."를 추가하는 방법

UITextView를 "UILabel과 같은" 것으로 사용하는 경우가 많습니다.줄임표 "..."를 사용하여 텍스트를 잘라냅니다.

이 경우 다음을 추가합니다.

 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은 이 Q&A 페이지에 기재되어 있는 문제에 시달리지 않습니다.

실제로 UILabel은 작업하기 어렵기 때문에 UIText View를 사용하는 것이 일반적입니다.특히 UILabel에 패딩만 정확하게 추가하는 것은 터무니없이 어렵습니다.

실제로 UILabel에 패딩을 올바르게 추가하는 방법에 대한 자세한 내용은 다음과 같습니다.UILabel공간/패드를 추가합니다.동적 높이 셀을 사용하여 어려운 레이아웃을 수행하는 경우 UILabel을 사용하여 어려운 레이아웃을 수행하는 것이 더 나을 수 있습니다.

이 회피책은 iOS 3.0이 출시된 2009년에 작성되었습니다.더 이상 적용되지 않습니다.

나도 똑같은 문제에 부딪혔고 결국엔 그걸 이용해서

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

는 nameField 입니다.UITextView제가 사용하던 폰트는 헬베티카 16포인트입니다.이것은 제가 그리고 있던 특정 필드 크기에 대한 맞춤 솔루션일 뿐입니다.그러면 왼쪽 오프셋이 왼쪽 오프셋과 같은 높이가 되고 위쪽 오프셋이 그려지는 상자에 대해 원하는 위치로 이동합니다.

또한 이는 다음에만 적용되는 것으로 보입니다.UITextViews하고 있는 즉 「」, 「」, 「」, 「」, 「」, 「」, 「」를 참조해 주세요.

nameField.textAlignment = NSTextAlignmentLeft;

를 들어 에 정렬하고, ㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴUIEdgeInsetsMake오른쪽 가장자리에는 전혀 영향이 없는 것 같습니다.

" . content " . content " . 하면 필드를 할 수 .또, 「의 「 」를 하지 않고, 에 대응할 수 .UITextViews.

지금까지의 몇개의 좋은 답변을 바탕으로 iOS 7.0+에서 동작하는 순수 Storyboard/Interface Builder 기반의 솔루션을 소개합니다.

다음 키에 대해 UITextView의 사용자 정의 런타임 속성을 설정합니다.

textContainer.lineFragmentPadding
textContainerInset

인터페이스 빌더

5의 경우 5의 경우UIEdgeInsetsMake(-8,-8,-8,-8);효과가 있는 것 같습니다.

실제 여백은 사용자의 폰트 크기 설정 등에 따라 달라질 수 있으므로 하드 코드화된 값에 대한 답변은 절대 피하겠습니다.

다음은 사용자 1687195의 답변입니다.textContainer.lineFragmentPadding(설명서에 의도된 용도가 아니기 때문에)

이것은 iOS 7 이상에서 매우 적합합니다.

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

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

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

7.16.과 iOS 6.1입니다.contentInset = {{-10, -5}, {0, 0}}.

사용자 정의 런타임 속성

산출량

이 모든 답변은 제목 질문을 다루고 있지만, OP 질문 본문에 제시된 문제에 대한 해결책을 제안하고 싶다.

텍스트 콘텐츠 크기

「」의 할 수 .UITextView은요, 사용법입니다.NSLayoutManager:

UITextView *textView;
CGSize textSize = [textView usedRectForTextContainer:textView.textContainer].size;

스크롤 한 전체 알 수 , 한 전체 내용은 러러 the this this, 그 this음음음음음 the the the the the the음음음음음음음음 the음 the the the the the the the the the the the보다 클 수 있습니다.UITextView을 사용하다 더 하다는 걸 됐어요.textView.contentSize텍스트가 차지하는 공간을 계산하기 때문입니다.를 들어, 빈 「」을 하면, 「」는 「」입니다.UITextView:

textView.frame.size = (width=246, height=50)
textSize = (width=10, height=16.701999999999998)
textView.contentSize = (width=246, height=33)
textView.textContainerInset = (top=8, left=0, bottom=8, right=0)

회선 높이

UIFont에는 지정된 글꼴의 줄 높이를 빠르게 가져올 수 있는 속성이 있습니다.의 줄 를 빨리 알 수.UITextView 라이선스:

UITextView *textView;
CGFloat lineHeight = textView.font.lineHeight;

표시 텍스트 크기 계산

"페이징" 효과를 처리하려면 실제로 표시되는 텍스트 양을 결정하는 것이 중요합니다. UITextView에는 고 has하 has has has has has has has has has has has라는 .textContainerInset실제와 실제의 차이입니다.UITextView.frame텍스트 그 자체입니다.표시되는 프레임의 실제 높이를 계산하려면 다음 계산을 수행합니다.

UITextView *textView;
CGFloat textViewHeight = textView.frame.size.height;
UIEdgeInsets textInsets = textView.textContainerInset;
CGFloat textHeight = textViewHeight - textInsets.top - textInsets.bottom;

페이징 크기 결정

눈에 , ' 정도인지', '어느 정도인지', '어느 정도인지', '어느 정도인지', '어느 정도인지'를 할 수 .textHeight textSize:

// where n is the page number you want
CGFloat pageOffsetY = textSize - textHeight * (n - 1);
textView.contentOffset = CGPointMake(textView.contentOffset.x, pageOffsetY);

// examples
CGFloat page1Offset = 0;
CGFloat page2Offset = textSize - textHeight
CGFloat page3Offset = textSize - textHeight * 2

이 모든 방법을 사용해, 인스톨을 건드리지 않고, 캐럿이나 텍스트내의 임의의 장소에 액세스 할 수 있었습니다.

.textContainerInset의 of의 UITextView:

textView.textContainerInset = UIEdgeInsetsMake(10, 10, 10, 10);

(위, 왼쪽, 아래, 오른쪽)

여기 Fattie의 매우 유용한 답변의 최신 버전이 있습니다.또한 iOS 10과 11에서 레이아웃을 사용할 수 있도록 두 개의 중요한 행이 추가되어 있습니다(아마도 하위 행에서도 마찬가지일 것입니다.

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

은 두 입니다.translatesAutoresizingMaskIntoConstraints = <true/false>★★★★★★★★★★★★★★★★!

이렇게 하면 내 모든 상황에서 놀랍게도 모든 마진을 제거할 수 있습니다!

★★★★★textView 응답자가 맨 수한 문제가 할 수 .최종 응답자를 사용하여 해결할 수 없는 이상한 하단 여백이 있을 수 있습니다.sizeThatFits승인된 답변에 언급된 방법.

했을 때 모든 , 가 textView를 만 TextView가 됩니다.firstResponder.

여기 스택 오버플로우에서 읽었습니다.translatesAutoresizingMaskIntoConstraints 콜간의 이 됩니다.

설정뿐만 두 설정에도 가 있습니다.setup() translatesAutoresizingMaskIntoConstraints 콜! 콜!

예를 들어, 이 기능은 에서 사용하는 뷰의 프레임을 계산할 때 매우 유용합니다. 이전에 사용하지 않았던 올바른 크기를 반환합니다.

앞서 언급한 답변과 같습니다.

Inspector에서 scrollEnabled를 해제하는 것을 잊지 마십시오!이 솔루션은 스토리보드에서도 실행 시에도 정상적으로 동작합니다.

끝이야, 이제 넌 정말 이야!

iOS 10의 경우 위아래 패딩 제거 시 다음 행이 작동합니다.

captionTextView.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0)

최신 스위프트:

self.textView.textContainerInset = .init(top: -2, left: 0, bottom: 0, right: 0)
self.textView.textContainer.lineFragmentPadding = 0

Swift 4, Xcode 9의 경우

다음 기능을 사용합니다.UITextView에서 텍스트 여백/패드를 변경할 수 있습니다.

public func UIEdgeInsetsMake(_ top: CGFloat, _ left: CGFloat, _ bottom: CGFloat, _ right: CGFloat) -> UIEdgeInsets

이 경우 다음과 같습니다.

 self.textView?.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0)

여기 앱의 모든 텍스트 보기에서 Apple의 기본 마진을 제거하는 간단한 확장 기능이 있습니다.

참고: Interface Builder는 이전 마진을 표시하지만 앱은 예상대로 작동합니다.

extension UITextView {

   open override func awakeFromNib() {
      super.awakeFromNib();
      removeMargins();
   }

   /** Removes the Apple textview margins. */
   public func removeMargins() {
      self.contentInset = UIEdgeInsetsMake(
         0, -textContainer.lineFragmentPadding,
         0, -textContainer.lineFragmentPadding);
   }
}

인셋 솔루션을 할 때 오른쪽과 아래쪽에는 패딩이 남아 있었습니다.또, 텍스트의 정렬로 문제가 발생.제가 찾은 유일한 확실한 방법은 텍스트 뷰를 경계에 잘린 다른 뷰 안에 넣는 것이었습니다.

Swift의 경우UI

TextView를 사용하여 UIViewRepresentable는, 「패딩」으로 .makeUIView 하다, 하다, 하다, 하다, 하다.

uiTextView.textContainerInset = UIEdgeInsets(top: 10, left: 18, bottom: 0, right: 18)

뭐든 원하는 대로 해

(iOS 11 Xcode 9.4.1) 텍스트 표시대한. 속성UIFont.preferred(forTextStyle:UIFontTextStyle)스타일과 Fattie가 언급한 첫 번째 답변입니다.그러나 textView를 설정할 때까지 Fattie의 답변은 기능하지 않았습니다.글꼴 속성.그렇지 않으면 UITextView가 계속 불규칙하게 동작합니다.

최신 Swift 버전을 찾는 사람이 있다면 아래 코드는 Xcode 10.2와 Swift 4.2에서 정상적으로 작동합니다.

yourTextView.textContainerInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)

textView 스크롤은 텍스트의 위치에도 영향을 미쳐 세로 중심이 아닌 것처럼 보이게 합니다.스크롤을 비활성화하고 상단 삽입을 0으로 설정하여 텍스트의 중심을 맞추는데 성공했습니다.

    textView.scrollEnabled = NO;
    textView.textContainerInset = UIEdgeInsetsMake(0, textView.textContainerInset.left, textView.textContainerInset.bottom, textView.textContainerInset.right);

어떤 이유에서인지 타이핑이 시작되기 전에는 커서가 중앙에 위치하지 않지만 타이핑을 시작하면 바로 텍스트가 중심이 됩니다.

didMoveToSuperView에 inset 및 lineFragmentPadding을 설정해야 합니다.

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

난 한 가지 더 접근 방법을 찾았다.UITextView의 서브뷰에서 텍스트를 포함한 뷰를 가져와 서브클래스의 layoutSubview 메서드로 설정하기:

- (void)layoutSubviews {
    [super layoutSubviews];

    const int textViewIndex = 1;
    UIView *textView = [self.subviews objectAtIndex:textViewIndex];
    textView.frame = CGRectMake(
                                 kStatusViewContentOffset,
                                 0.0f,
                                 self.bounds.size.width - (2.0f * kStatusViewContentOffset),
                                 self.bounds.size.height - kStatusViewContentOffset);
}

을 설정하고 맨패딩을 피하고 즉 태그를 .div ★★★★★★★★★★★★★★★★★」p.

내 경우에는 이것이 이유였다.을 예를 태그의 을 '알다'로할 수 .span붙이다

HTML을 UITextView로 해석하기 위해 여기에 온 사람은 p 태그 "/n"을 닫는 새로운 행을 삭제하기만 하면 됩니다.NSMutableAttributedString을 사용하고 있을 것으로 생각됩니다.

if let lastCharacter = attributedString.string.last, lastCharacter == "\n" {
    attributedString.deleteCharacters(in: NSRange(location:(attributedString.length) - 1, length:1))
}
[firstNameTextField setContentVerticalAlignment:UIControlContentVerticalAlignmentCenter];

언급URL : https://stackoverflow.com/questions/746670/how-to-lose-margin-padding-in-uitextview

반응형