ฉันจะบังคับให้ UITextView เลื่อนขึ้นไปด้านบนทุกครั้งที่เปลี่ยนข้อความได้อย่างไร


100

ตกลงฉันมีปัญหากับไฟล์UITextView. นี่คือปัญหา:

ฉันเพิ่มข้อความลงในไฟล์UITextView. จากนั้นผู้ใช้คลิกสองครั้งเพื่อเลือกบางสิ่ง จากนั้นฉันเปลี่ยนข้อความในUITextView(ตามโปรแกรมด้านบน) และUITextView เลื่อนไปที่ด้านล่างของหน้าที่มีเคอร์เซอร์

อย่างไรก็ตามนั่นไม่ใช่ที่ที่ผู้ใช้คลิก มันจะเลื่อนไปที่ด้านล่างเสมอUITextViewไม่ว่าผู้ใช้จะคลิกที่ใดก็ตาม

นี่คือคำถามของฉัน: ฉันจะบังคับUITextViewให้เลื่อนขึ้นไปด้านบนทุกครั้งที่เปลี่ยนข้อความได้อย่างไร? ฉันได้ลองcontentOffsetและscrollRangeToVisible. ไม่ทำงาน

ข้อเสนอแนะใด ๆ จะได้รับการชื่นชม

คำตอบ:


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

สิ่งนี้ทำเพื่อฉัน

เวอร์ชัน Swift (Swift 4.1 พร้อม iOS 11 บน Xcode 9.3):

note.setContentOffset(.zero, animated: true)

13
ไม่ช่วยฉัน
Dmitry

6
วิธีนี้ใช้งานได้ แต่เหตุใดจึงจำเป็นต่อไป? ตรรกะการเลื่อนของ Apple จำเป็นต้องได้รับการปรับแต่งมีการกระโดดกระโดดมากเกินไปเพื่อให้สิ่งต่างๆทำงานตามที่ควรจะเป็นโดยอัตโนมัติในกรณีส่วนใหญ่
John Contarino

4
ใช้ได้กับฉันใน iOS 9 แต่ไม่เร็วกว่าviewDidAppear()นั้น
Murray Sagal

4
คุณสามารถเรียกสิ่งนี้ได้เร็วกว่า viewDidAppear () โดยเรียกมันใน viewDidLayoutSubviews ()
arcady bob

ฉันได้เพิ่มมุมมองข้อความในเซลล์ของตารางดังนั้นฉันจึงตั้งค่านี้ในเซลล์สำหรับแถว แต่ไม่ทำงาน
Chandni

67

ถ้าใครมีปัญหานี้ใน iOS 8 ผมพบว่าเพียงแค่การตั้งค่าUITextView'sคุณสมบัติข้อความแล้วโทรscrollRangeToVisibleกับNSRangeด้วยlocation:0, length:0ทำงาน มุมมองข้อความของฉันไม่สามารถแก้ไขได้และฉันทดสอบทั้งแบบเลือกได้และแบบเลือกไม่ได้ (การตั้งค่าทั้งสองอย่างไม่มีผลต่อผลลัพธ์) นี่คือตัวอย่าง Swift:

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

ขอบคุณไม่มีข้อใดที่ได้ผลสำหรับฉัน ตัวอย่างของคุณทำ
user1244109

ใช้งานได้ แต่เราได้รับภาพเคลื่อนไหวแบบเลื่อนที่ต้องปิดใช้งานฉันชอบปิดการใช้งานการเลื่อนและเปิดใช้งานเหมือนที่ @miguel แนะนำ
Warpzit

วัตถุประสงค์ -C: [myTextView scrollRangeToVisible: NSMakeRange (0, 0)];
Stateful

ดูเหมือนจะใช้ไม่ได้อีกต่อไป iOS 9 และ Xcode 7.3.1: /
wasimsandhu

Swift 3 Stll ใช้งานได้! :) เพียงแค่คัดลอกบรรทัดนี้ในวิธี UITextFielDelegate ของคุณ `func textViewDidEndEditing (_ textView: UITextView) {textView.scrollRangeToVisible (NSRange (ตำแหน่ง: 0, ความยาว: 0))}`
lifewithelliott

46

และนี่คือทางออกของฉัน ...

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

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

5
ฉันไม่ชอบโซลูชันนี้ แต่อย่างน้อยใน iOS 9 เบต้า 5 มันเป็นสิ่งเดียวที่เหมาะกับฉัน ฉันสมมติว่าโซลูชันอื่น ๆ ส่วนใหญ่สมมติว่ามุมมองข้อความของคุณสามารถมองเห็นได้แล้ว ในกรณีของฉันมันไม่เป็นความจริงเสมอไปดังนั้นฉันจึงต้องปิดการเลื่อนไปเรื่อย ๆ จนกว่าจะปรากฏ
robotspacer

1
นี่เป็นสิ่งเดียวที่ใช้ได้ผลสำหรับฉันด้วย iOS 9 โดยใช้ textview ที่แก้ไขไม่ได้
SeanR

1
สิ่งนี้ใช้ได้กับฉัน iOS 8 ที่แก้ไขข้อความไม่ได้พร้อมสตริงที่มาจากแหล่งที่มา ใน viewWillAppear - ไม่ทำงาน
Tina Zh

ฉันเห็นด้วยกับ @robotspacer และวิธีนี้ยังคงเป็นวิธีเดียวที่เหมาะกับฉัน
lerp90

สำหรับฉันวิธีนี้ใช้ได้เฉพาะกับข้อความสั้น ๆ (ประกอบ) เมื่อมีข้อความที่ยาวขึ้นข้อผิดพลาดในการเลื่อน UITextView จะยังคงมีชีวิตอยู่ :-) วิธีแก้ปัญหา (น่าเกลียดเล็กน้อย) ของฉันคือการใช้ dispatch_after ด้วยการหน่วงเวลา 2 วินาทีเพื่อเปิดใช้งานการเลื่อนอีกครั้ง ดูเหมือนว่า UITextView จะต้องใช้เวลาสักเล็กน้อยในการจัดวางรูปแบบข้อความ ...
LaborEtArs

38

โทร

scrollRangeToVisible(NSMakeRange(0, 0))

ใช้งานได้ แต่โทรเข้ามา

override func viewDidAppear(animated: Bool)

4
ฉันมั่นใจว่ามันใช้ได้กับฉันใน viewDidAppear เท่านั้น
ฉ.

2
นี่เป็นเพียงคนเดียวที่เหมาะกับฉัน ขอบคุณ. แต่คุณจะปิดการใช้งานภาพเคลื่อนไหวที่ฉันคิดว่าน่ารำคาญเล็กน้อยได้อย่างไร?
rockhammer

แม้ว่าวิธีนี้จะได้ผล แต่วิธีแก้ปัญหาของ I @Maria จะดีกว่าเพราะวิธีนี้ไม่ได้แสดง "กระโดด" สั้น ๆ
Sipke Schoorstra

1
ฉันเอาความคิดเห็นสุดท้ายของฉันกลับ; นี่เป็นคำตอบที่ดีที่สุดสำหรับฉันเนื่องจากใช้งานได้ทั้งบน iOS 10 และ iOS 11 ในขณะที่คำตอบของ @ Maria ใช้ไม่ได้ผลบน iOS 11
Sipke Schoorstra

@SipkeSchoorstra ดูคำตอบของฉันด้านล่างเพื่อให้ใช้งานได้โดยไม่ต้องกระโดดใด ๆ (โดยใช้ KVO)
Terry

29

ฉันใช้ attributedString ใน HTML โดยไม่สามารถแก้ไขมุมมองข้อความได้ การตั้งค่าชดเชยเนื้อหาก็ไม่ได้ผลสำหรับฉันเช่นกัน สิ่งนี้ใช้ได้กับฉัน: ปิดใช้งานการเลื่อนเปิดใช้งานตั้งค่าข้อความแล้วเปิดใช้งานการเลื่อนอีกครั้ง

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

ฉันมี textView อยู่ใน tableViewCell ในกรณีนี้ textView จะเลื่อนไปที่ประมาณ. 50%. วิธีนี้ง่ายพอ ๆ กับตรรกะ ขอบคุณ
Julian F.Winert

1
@ JulianF Weinert สิ่งนี้ดูเหมือนจะใช้ไม่ได้กับ iOS10 ฉันมีสถานการณ์เดียวกับคุณกับ textView ใน tableViewCell ฉันไม่ได้ใช้ความสามารถในการแก้ไขของ textView ฉันแค่ต้องการข้อความที่เลื่อนได้ แต่ textView จะเลื่อนไปที่ประมาณ 50% ตามที่คุณพูดเสมอ ฉันได้ลองคำแนะนำอื่น ๆ ทั้งหมดด้วยการตั้งค่า setContentOffset และ scrollRangeToVisible ในโพสต์นี้ ไม่มีงานทำ มีอะไรอีกที่คุณอาจทำเพื่อทำงานนี้?
JeffB6688

@ JeffB6688 ขอโทษนะไม่ใช่ มันนานมากแล้ว ... อาจจะเป็นอีกมุมมองหนึ่งของการเปิดตัว iOS "ใหม่"?
Julian F.Winert

แต่ไม่สมบูรณ์บน iOS 11.2 น่าเสียดาย คำตอบของ Onlu @RyanTCB ใช้ได้ทั้งบน iOS 10 และ iOS 11
Sipke Schoorstra

สิ่งนี้ใช้งานได้ดีสำหรับฉันใน iOS 9, 10 และ 11 แต่ฉันต้องเปิดใช้งานเพื่อviewDidAppearเป็นส่วนหนึ่งของการแก้ไขที่จริงจังในวงกว้างขึ้น
MadProgrammer

19

เนื่องจากวิธีแก้ปัญหาเหล่านี้ไม่ได้ผลสำหรับฉันและฉันเสียเวลามากเกินไปในการรวบรวมวิธีแก้ปัญหาในที่สุดสิ่งนี้ก็แก้ไขได้สำหรับฉัน

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)
    })
}

นี่เป็นเรื่องโง่มากที่นี่ไม่ใช่พฤติกรรมเริ่มต้นสำหรับการควบคุมนี้

ฉันหวังว่านี่จะช่วยคนอื่นได้


2
สิ่งนี้มีประโยชน์มาก! ฉันต้องเพิ่ม: self.automaticallyAdjustsScrollViewInsets = NO; ไปยังมุมมองที่มี UITextView เพื่อให้ทำงานได้เต็มที่
jengelsma

ฉันทำให้มันใช้งานได้ใน SWIFT 3 เท่านั้นโดยมีการself.textView.contentOffset.yคำนวณออฟเซตอื่นตามคำตอบนี้: stackoverflow.com/a/25366126/1736679
Efren

ทำงานให้ฉันเมื่อฉันปรับให้เข้ากับไวยากรณ์ล่าสุดสำหรับ Swift 3
hawmack13

เห็นด้วยอย่างยิ่งว่านี่มันบ้าแค่ไหน? ขอบคุณสำหรับการแก้ปัญหา
ajonno

18

ฉันไม่แน่ใจว่าเข้าใจคำถามของคุณหรือเปล่า แต่คุณกำลังพยายามเลื่อนมุมมองขึ้นไปด้านบน ถ้าเป็นเช่นนั้นคุณควรทำ

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


1
@SamStewart ดูเหมือนว่าลิงก์จะใช้งานไม่ได้นำไปสู่หน้าบัญชีของฉันเสมอ (ล็อกอินแล้ว) คุณสามารถให้ข้อมูลเพิ่มเติมเกี่ยวกับโซลูชันที่พวกเขาเสนอได้หรือไม่?
uliwitness

@uliwitness นี้เป็นซุปเปอร์ข้อมูลเก่าตอนนี้ผมจะแนะนำให้พยายามเป็นทรัพยากรที่ทันสมัยมากขึ้นแทนการโพสต์เก่า 8 ปี iOS API มีการเปลี่ยนแปลงอย่างมากในช่วง 8 ปีที่ผ่านมา
Benjamin Sussman

1
ฉันพยายามค้นหาข้อมูลที่ใหม่กว่าแล้ว ถ้าคุณรู้ว่าฉันสามารถหาได้ที่ไหนฉันจะขอบคุณ ยังคงเป็นประเด็นเดิม :(
uliwitness

ขอบคุณสิ่งนี้ได้ผลสำหรับฉันเพราะฉันได้ตั้งค่าสิ่งที่ใส่เข้าไปในแอตทริบิวต์รันไทม์ที่กำหนดโดยผู้ใช้TextView.scrollRectToVisible(CGRect(x: 0,y: 0,width: 1,height: 1), animated: false)
Kurt Lane

13

สำหรับ iOS 10 และ Swift 3 ฉันทำ:

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

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

ทำงานให้ฉันไม่แน่ใจว่าคุณกำลังมีปัญหากับ Swift และ iOS เวอร์ชันล่าสุดหรือไม่


ทางออกที่ดีที่จะปฏิบัติตาม!
iChirag

ฉันมีปัญหาในการเลื่อน UITextView ใน UIView ที่ควบคุมโดย UIPageViewController (หน้าเหล่านี้แสดงหน้าจอวิธีใช้ / เกี่ยวกับของฉัน) โซลูชันของคุณใช้ได้กับทุกหน้ายกเว้นหน้าแรก การปัดไปที่หน้าใด ๆ และกลับไปที่หน้าแรกจะแก้ไขตำแหน่งการเลื่อนของหน้าแรกนั้น ฉันลองเพิ่ม. isScrollEnabled = False อีกอันลงใน viewWillAppear แต่ก็ไม่มีผล ฉันนิ่งงันว่าทำไมหน้าแรกจึงทำงานแตกต่างจากหน้าอื่น ๆ
Wayne Henderson

[อัปเดต] เพิ่งแก้ไข! แนะนำการหน่วงเวลา 0.5 วินาทีก่อนทริกเกอร์. isScrollEnabled = true จะแก้ไขปัญหาการโหลดครั้งแรก
Wayne Henderson

ดีมาก . . .
Maysam R

ทำงานอย่างมีเสน่ห์ ทางออกเดียวที่เหมาะกับฉัน คุณเป็นผู้ชาย
Lazy Ninja

10

ฉันมีคำตอบที่อัปเดตซึ่งจะทำให้ textview ปรากฏขึ้นอย่างถูกต้องและผู้ใช้ไม่พบภาพเคลื่อนไหวแบบเลื่อน

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

ทำไมคุณถึงทำในคิวหลักไซน์ viewWillAppear กำลังทำงานบนเมนคิว?
karthikPrabhu Alagu

1
มีดวงจันทร์มากเกินไปสำหรับฉันที่จะจำได้ แต่มันอยู่ที่นี่: stackoverflow.com/a/17490329/4750649
MacInnis

8

นี่คือวิธีการทำงานบน iOS 9 Release เพื่อให้ textView เลื่อนไปด้านบนก่อนที่จะปรากฏบนหน้าจอ

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

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

1
นี่เป็นเคล็ดลับ อนึ่งมันสอนฉันบางสิ่งที่สำคัญมาก: 'มุมมอง' ใน 'viewwillappear' ไม่ได้หมายถึง self.view เท่านั้น แต่ดูเหมือนกับทุกมุมมอง ไม่?
Sjakelien

8

นั่นคือวิธีที่ฉันทำ

Swift 4:

extension UITextView {

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

 }

นี่เป็นวิธีเดียวที่ให้ผลลัพธ์ที่ดีที่สุดสำหรับฉัน ฉันโหวต
smoothBlue

7

สิ่งนี้ได้ผลสำหรับฉัน

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

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

นี่เป็นเรื่องแปลกมาก ในอุปกรณ์ส่วนใหญ่การตัดสายDispatchQueue.main.async(...ไม่จำเป็น แต่ด้วยเหตุผลบางประการบน (เช่น) iPhone 5s (iOS 12.1) จะไม่ทำงานเว้นแต่คุณจะส่ง แต่ตามที่รายงานโดย call stack บนดีบักเกอร์viewWillAppear() กำลังรันอยู่ในคิวหลักในทุกกรณี ... - WTF, Apple ???
Nicolas Miari

2
ฉันก็สงสัยเหมือนกันว่าทำไมฉันต้องส่งไปที่คิวหลักอย่างชัดเจนแม้ว่าฉันจะเรียกใช้เหตุการณ์ทั้งหมดในคิวหลัก แต่สิ่งนี้ได้ผลสำหรับฉัน
Ankit garg

6

ลองทำเช่นนี้เพื่อเลื่อนเคอร์เซอร์ไปที่ด้านบนสุดของข้อความ

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

ดูว่าจะไปอย่างไร ตรวจสอบให้แน่ใจว่าคุณเรียกสิ่งนี้หลังจากเหตุการณ์ทั้งหมดของคุณเริ่มขึ้นหรือสิ่งที่คุณทำอยู่เสร็จ


ลองผู้ชายไม่มีโชค ดูเหมือนว่าจะมีบางอย่างกับ firstResponder ข้อเสนอแนะอื่น ๆ ?
Sam Stewart

มีปัญหาเดียวกันกับตำแหน่งเคอร์เซอร์มันใช้ได้สำหรับฉัน ... +1 ที่ดีสำหรับสิ่งนั้น
Dhaval

ฉันได้รับแอนิเมชั่นจากล่างขึ้นบน แต่ฉันไม่ได้ต้องการแบบนั้นดังนั้นจะเอาออกได้อย่างไร
Dhaval

2
ไม่เลื่อนไปด้านบน (น้อยกว่าไม่กี่พิกเซล)
Dmitry

6

ปัญหาของฉันคือการตั้งค่า textView ให้เลื่อนขึ้นไปด้านบนเมื่อมุมมองปรากฏขึ้น สำหรับ iOS 10.3.2 และ Swift 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
}

5

รวมคำตอบก่อนหน้านี้ตอนนี้ควรใช้:

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

lmao สิ่งเดียวที่ใช้ได้ผลสำหรับฉันว่าโง่แค่ไหน ฉันสามารถลบscrollRangeToVisibleแม้ว่า
Jordan H

คุณจะต้องแทนที่ NSRange (0,0) ด้วย NSMakeRange (0,0)
RobP


5

เพียงแค่คุณใช้รหัสนี้ได้

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

4

คำตอบ Swift 2:

textView.scrollEnabled = false

/* Set the content of your textView here */

textView.scrollEnabled = true

ซึ่งจะป้องกันไม่ให้ textView เลื่อนไปที่ท้ายข้อความหลังจากตั้งค่า


4

ใน Swift 3:

  • viewWillLayoutSubviewsเป็นที่สำหรับทำการเปลี่ยนแปลง viewWillAppearควรจะทำงานเช่นกัน แต่มีเหตุผลรูปแบบควรจะดำเนินการในviewWillLayoutSubviews

  • เกี่ยวกับวิธีการทั้งscrollRangeToVisibleและsetContentOffsetจะทำงาน อย่างไรก็ตามsetContentOffsetอนุญาตให้ปิดหรือเปิดภาพเคลื่อนไหวได้

สมมติว่า UITextViewมีชื่อเป็นyourUITextView นี่คือรหัส:

// 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)
}

viewWillLayoutSubviews เรียกว่าการปรับขนาดมุมมองใด ๆ โดยทั่วไปแล้วไม่ใช่สิ่งที่คุณต้องการ
uliwitness

4

ฉันต้องเรียกสิ่งต่อไปนี้ภายในviewDidLayoutSubviews (การเรียกภายใน viewDidLoad เร็วเกินไป):

    myTextView.setContentOffset(.zero, animated: true)

3

สิ่งนี้ได้ผลสำหรับฉัน ขึ้นอยู่กับคำตอบของ 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)];
}

3
-(void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];

    [textview setContentOffset:CGPointZero animated:NO];
}

viewWillLayoutSubviews เรียกว่าการปรับขนาดมุมมองใด ๆ โดยทั่วไปแล้วไม่ใช่สิ่งที่คุณต้องการ
uliwitness

3
-(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]; ใช้งานไม่ได้ในบางครั้ง (ฉันไม่รู้ว่าทำไม) ดังนั้นให้ใช้ scrollrangetovisible แทน


2

แก้ไขปัญหา: iOS = 10.2 Swift 3 UITextView

ฉันเพิ่งใช้บรรทัดต่อไปนี้:

displayText.contentOffset.y = 0

1
ทำงานแล้ว (iOS 10.3)! ฉันเพิ่มมันเข้าไปข้างในviewDidLayoutSubviewsดังนั้นมันจึงเกิดขึ้นเมื่อหน้าจอหมุน มิฉะนั้นการชดเชยเนื้อหาจะไม่ตรงแนว
Pup

2

ฉันมีปัญหา แต่ในกรณีของฉัน textview คือมุมมองย่อยของมุมมองที่กำหนดเองบางส่วนและเพิ่มลงใน ViewController ไม่มีวิธีแก้ปัญหาใดที่ใช้ได้ผลสำหรับฉัน เพื่อแก้ปัญหาเพิ่มความล่าช้า 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
}

1

สำหรับฉันรหัสนี้ใช้งานได้ดี:

    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 เลื่อนไปที่ส่วนท้ายของข้อความจากนั้น scrollRangeToVisible เลื่อนขึ้นตามค่าของ scrollToLocation ดังนั้นตำแหน่งที่ต้องการจะปรากฏในบรรทัดแรกของ scrollView


1

สำหรับฉันใน iOS 9 มันหยุดทำงานให้ฉันด้วยสตริงที่มาจากแหล่งที่มาด้วยวิธีการ scrollRangeToVisible (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)
}

1

ลองใช้โซลูชัน 2 บรรทัดนี้:

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

สิ่งนี้ได้ผลสำหรับฉัน UITextView ของฉันอยู่ใน UICollectionVewCell ฉันสงสัยว่า scrollRangeToVisible เลื่อนไปยังจุดที่ไม่ถูกต้องเว้นแต่ว่าเค้าโครงจะคำนวณอย่างถูกต้อง
John Fowler

1

นี่คือรหัสของฉัน มันทำงานได้ดี

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()
      }
  }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.