programing

텍스트를 변경할 때마다 UITtextView가 맨 위로 스크롤되도록 하려면 어떻게 해야 합니까?

goodsources 2023. 10. 23. 21:47
반응형

텍스트를 변경할 때마다 UITtextView가 맨 위로 스크롤되도록 하려면 어떻게 해야 합니까?

좋아요, 제가 문제가 있어서요UITextView과 같습니다 문제는 다음과 같습니다.

에 텍스트를 추가합니다.UITextView그런 가 두 번 그런 다음 사용자는 두 번 클릭하여 무언가를 선택합니다.그런 다음 텍스트를 바꿉니다.UITextView(위와 같이 프로그램적으로) 및UITextView커서가 있는 페이지 하단으로 스크롤합니다.

그러나 사용자가 클릭한 위치가 아닙니다.항상 맨 아래로 스크롤합니다.UITextView사용자가 클릭한 위치에 관계없이.

그래서 제 질문은 이렇습니다.어떻게 하면 강제로UITextView텍스트를 변경할 때마다 맨 위로 스크롤할 수 있습니까?노력했습니다.contentOffset그리고.scrollRangeToVisible 둘 다 안 돼요.

어떤 제안이든 감사히 받겠습니다.

UITextView*note;
[note setContentOffset:CGPointZero animated:YES];

이거면 돼요.

Swift 버전 (Xcode 9.3에서 iOS 11이 탑재된 Swift 4.1):

note.setContentOffset(.zero, animated: true)

iOS 8에서 이 문제를 가진 사람이 있다면, 저는 그냥 설정을 하는 것을 발견했습니다.UITextView's텍스트 속성, 호출scrollRangeToVisible의 소리와 함께NSRange와 함께location:0,length:0했습니다. . 텍스트 할 수 없었고 한 것과 수 없는 테스트했습니다에 영향을 주지 않았습니다).텍스트 보기를 편집할 수 없었고, 선택 가능한 것과 선택할 수 없는 것을 모두 테스트했습니다(설정은 결과에 영향을 주지 않았습니다).스위프트의 예는 다음과 같습니다.

myTextView.text = "Text that is long enough to scroll"
myTextView.scrollRangeToVisible(NSRange(location:0, length:0))

그리고 여기 내 해결책이...

    override func viewDidLoad() {
        textView.scrollEnabled = false
        textView.text = "your text"
    }

    override func viewDidAppear(animated: Bool) {
        textView.scrollEnabled = true
    }

부르기

scrollRangeToVisible(NSMakeRange(0, 0))

효과는 있지만 불러들입니다.

override func viewDidAppear(animated: Bool)

텍스트 뷰를 편집할 수 없는 HTML에서 attributedString을 사용하고 있었습니다.내용 오프셋을 설정하는 것도 저에게는 효과가 없었습니다.스크롤 활성화를 해제하고 텍스트를 설정한 다음 스크롤을 다시 활성화하는 것이 효과적이었습니다.

[yourTextView setScrollEnabled:NO];
yourTextView.text = yourtext;
[yourTextView setScrollEnabled:YES];

이 솔루션 중 어느 것도 제게 효과가 없었고 솔루션을 구성하는 데 너무 많은 시간을 낭비했기 때문에 결국 해결되었습니다.

override func viewWillAppear(animated: Bool) {
    dispatch_async(dispatch_get_main_queue(), {
        let desiredOffset = CGPoint(x: 0, y: -self.textView.contentInset.top)
        self.textView.setContentOffset(desiredOffset, animated: false)
    })
}

이 컨트롤에 대한 기본 동작이 아니라는 것은 정말 어리석은 일입니다.

이것이 다른 사람에게 도움이 되길 바랍니다.

질문을 이해할 수 있을지 모르겠지만, 보기를 그냥 맨 위로 스크롤하려고 하시는 건가요?만약 그렇다면 당신은 해야 합니다.

[textview scrollRectToVisible:CGRectMake(0,0,1,1) animated:YES];

iOS 10 및 Swift 3의 경우 다음과 같이 수행했습니다.

override func viewDidLoad() {
    super.viewDidLoad()
    textview.isScrollEnabled = false
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    textView.isScrollEnabled = true
}

스위프트와 iOS의 최신 버전에 문제가 있는지 잘 모르겠습니다.

이렇게 iOS 9 Release에서 작동하여 화면에 표시되기 전에 보기 텍스트가 위쪽으로 스크롤됩니다.

- (void)viewDidLoad
{
    [super viewDidLoad];
    textView.scrollEnabled = NO;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    textView.scrollEnabled = YES;
}

사용자가 스크롤 애니메이션을 경험하지 않아도 텍스트 뷰가 제대로 나타나는 업데이트된 답변이 있습니다.

override func viewWillAppear(animated: Bool) {
    dispatch_async(dispatch_get_main_queue(), {
        self.introductionText.scrollRangeToVisible(NSMakeRange(0, 0))
    })

저는 그렇게 했습니다.

스위프트 4:

extension UITextView {

    override open func draw(_ rect: CGRect)
    {
        super.draw(rect)
        setContentOffset(CGPoint.zero, animated: false)
    }

 }

이거 나한테 통했어요.

  override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    DispatchQueue.main.async {
      self.textView.scrollRangeToVisible(NSRange(location: 0, length: 0))
    }
  }

다음 인사이드뷰 DidLayoutSubviews를 호출해야 했습니다(인사이드뷰 DidLoad를 호출하는 것은 너무 빨랐습니다).

    myTextView.setContentOffset(.zero, animated: true)

커서를 텍스트 맨 위로 이동하려면 이 작업을 수행합니다.

NSRange r  = {0,0};
[yourTextView setSelectedRange:r];

그것이 어떻게 되는지 보세요.모든 이벤트가 발생했거나 수행 중인 작업이 모두 완료된 후에 이 문제를 해결해야 합니다.

내 문제는 보기가 나타나면 textView를 상단으로 스크롤하도록 설정하는 것입니다.iOS 10.3.2와 스위프트 3의 경우.

해결책 1:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    // It doesn't work. Very strange.
    self.textView.setContentOffset(CGPoint.zero, animated: false)
}
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    // It works, but with an animation effection.
    self.textView.setContentOffset(CGPoint.zero, animated: false)
}

해결책 2:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    // It works.       
    self.textView.contentOffset = CGPoint.zero
}

이 코드를 사용하면 됩니다.

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    textView.scrollRangeToVisible(NSMakeRange(0, 0))
}

이전의 답변을 종합하면, 이제는 다음과 같이 작동합니다.

talePageText.scrollEnabled = false
talePageText.textColor = UIColor.blackColor()
talePageText.font = UIFont(name: "Bradley Hand", size: 24.0)
talePageText.contentOffset = CGPointZero
talePageText.scrollRangeToVisible(NSRange(location:0, length:0))
talePageText.scrollEnabled = true
[txtView setContentOffset:CGPointMake(0.0, 0.0) animated:YES];

이 코드 줄은 제게 적합합니다.

스위프트 2 답변:

textView.scrollEnabled = false

/* Set the content of your textView here */

textView.scrollEnabled = true

이렇게 하면 텍스트 보기를 설정한 후 텍스트 끝까지 스크롤할 수 없습니다.

스위프트 3:

  • viewWillLayoutSubviews는 변경할 위치입니다.viewWillAppear도 작동해야 하지만 논리적으로는 viewWillLayoutSubviews에서 레이아웃을 수행해야 합니다.

  • 메서드와 관련하여 RangeToVisible 스크롤 및 setContentOffset이 모두 작동합니다.그러나 setContentOffset을 사용하면 애니메이션을 끄거나 켤 수 있습니다.

UITextView의 이름이 다음 이름으로 지정되었다고 가정합니다.UIT textView.코드는 다음과 같습니다.

// Connects to the TextView in the interface builder.
@IBOutlet weak var yourUITextView: UITextView!

/// Overrides the viewWillLayoutSubviews of the super class.
override func viewWillLayoutSubviews() {

    // Ensures the super class is happy.
    super.viewWillLayoutSubviews()

    // Option 1:
    // Scrolls to a range of text, (0,0) in this very case, animated.
    yourUITextView.scrollRangeToVisible(NSRange(location: 0, length: 0))

    // Option 2:
    // Sets the offset directly, optional animation.
    yourUITextView.setContentOffset(CGPoint(x: 0, y: 0), animated: false)
}

저는 이게 통했어요.이는 RyanTCBs의 답변을 기반으로 하지만 동일한 솔루션의 Objective-C 변형입니다.

- (void) viewWillAppear:(BOOL)animated {
    // For some reason the text view, which is a scroll view, did scroll to the end of the text which seems to hide the imprint etc at the beginning of the text.
    // On some devices it is not obvious that there is more text when the user scrolls up.
    // Therefore we need to scroll textView to the top.
    [self.textView scrollRangeToVisible:NSMakeRange(0, 0)];
}
-(void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];

    [textview setContentOffset:CGPointZero animated:NO];
}
-(void) viewDidAppear:(BOOL)animated{
[mytextView scrollRangeToVisible:NSMakeRange(0,0)];}

- (void)viewWillAppear:(BOOL)animated{
[mytextView scrollRangeToVisible:NSMakeRange(0,0)];}
  • ViewWillappear사용자가 알아차리기 전에 즉시 실행할 것입니다.ViewDidDisappear섹션은 느릿느릿하게 그것을 애니메이션화할 것입니다.
  • [mytextView setContentOffset:CGPointZero animated:YES];작동하지 않는 경우가 있으므로(이유를 알 수 없음) 스크롤 범위를 사용하여 볼 수 있습니다.
[self.textView scrollRectToVisible:CGRectMake(0, 0, 320, self.textView.frame.size.height) animated:NO];

문제 해결: iOS = 10.2 Swift 3 UITextView

저는 그냥 다음 대사를 사용했습니다.

displayText.contentOffset.y = 0

문제가 있었지만 텍스트 뷰의 경우 일부 사용자 정의 뷰의 하위 뷰를 View Controller에 추가했습니다.어떤 해결책도 제게 효과가 없었습니다.문제를 해결하기 위해 0.1초 지연을 추가한 다음 스크롤을 활성화했습니다.그것은 나에게 효과가 있었다.

textView.isScrollEnabled = false
..
textView.text = // set your text here

let dispatchTime = DispatchTime.now() + 0.1
DispatchQueue.main.asyncAfter(deadline: dispatchTime) {
   self.textView.isScrollEnabled = true
}

저에게는 이 코드가 잘 작동합니다.

    textView.attributedText = newText //or textView.text = ...

    //this part of code scrolls to top
    textView.contentOffset.y = -64
    textView.scrollEnabled = false
    textView.layoutIfNeeded() //if don't work, try to delete this line
    textView.scrollEnabled = true

정확한 위치로 스크롤하여 화면 맨 위에 표시하려면 다음 코드를 사용합니다.

    var scrollToLocation = 50 //<needed position>
    textView.contentOffset.y = textView.contentSize.height
    textView.scrollRangeToVisible(NSRange.init(location: scrollToLocation, length: 1))

contentOffset.y를 설정하면 텍스트 끝까지 스크롤한 다음 RangeToVisible을 스크롤 ToLocation 값까지 스크롤합니다.따라서 스크롤 보기의 첫 번째 줄에 필요한 위치가 나타납니다.

iOS 9의 경우 스크롤RangeToVisible(1행은 굵은 글꼴, 다른 행은 일반 글꼴) 메서드의 속성 문자열로 작동하지 않았습니다.

그래서 나는 다음을 사용해야 했습니다.

textViewMain.attributedText = attributedString
textViewMain.scrollRangeToVisible(NSRange(location:0, length:0))
delay(0.0, closure: { 
                self.textViewMain.scrollRectToVisible(CGRectMake(0, 0, 10, 10), animated: false)
            })

여기서 지연은 다음과 같습니다.

func delay(delay:Double, closure:()->Void) {
    dispatch_after(
        dispatch_time(
            DISPATCH_TIME_NOW,
            Int64(delay * Double(NSEC_PER_SEC))
        ),
        dispatch_get_main_queue(), closure)
}

이 두 줄 솔루션을 사용해 보십시오.

view.layoutIfNeeded()
textView.contentOffset = CGPointMake(textView.contentInset.left, textView.contentInset.top)

여기 제 코드가 있습니다.잘 작동합니다.

class MyViewController: ... 
{
  private offsetY: CGFloat = 0
  @IBOutlet weak var textView: UITextView!
  ...

  override viewWillAppear(...) 
  {
      ...
      offsetY = self.textView.contentOffset.y
      ...
  }
  ...
  func refreshView() {
      let offSetY = textView.contentOffset.y
      self.textView.setContentOffset(CGPoint(x:0, y:0), animated: true)
      DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
        [unowned self] in
        self.textView.setContentOffset(CGPoint(x:0, y:self.offSetY), 
           animated: true)
        self.textView.setNeedsDisplay()
      }
  }

언급URL : https://stackoverflow.com/questions/1234242/how-do-i-force-a-uitextview-to-scroll-to-the-top-every-time-i-change-the-text

반응형