จะปิดการใช้งานการเลื่อนแนวนอนของ UIScrollView ได้อย่างไร?


92

ฉันมีUIViewสปริงบอร์ดเหมือน iPhone ฉันได้สร้างมันขึ้นมาโดยใช้UIScrollViewและUIButtons. ฉันต้องการปิดการใช้งานการเลื่อนแนวนอนใน scrollview ดังกล่าว ฉันต้องการเพียงการเลื่อนในแนวตั้ง ฉันจะทำสิ่งนี้ให้สำเร็จได้อย่างไร?


5
คุณควรเปลี่ยนชื่อของคุณ: คุณขอแนวนอนในคำถามและแนวตั้งในชื่อเรื่อง ผู้คนพบคำถามของคุณในเครื่องมือค้นหาในภายหลังดังนั้นจึงยังคงมีความสำคัญอีก 2 ปีต่อมา :)
Julien

@RahulVyas ผู้ชายข้างบนมีประเด็น การเปลี่ยนชื่อจะช่วยลดความสับสนสำหรับผู้เริ่มต้นที่มาที่นี่ผ่านเครื่องมือค้นหา (เช่นฉัน;))
SpacyRicochet

ได้แก้ไขชื่อในนามของผู้โพสต์ (แม้ว่าขณะนี้กำลังรอการตรวจสอบโดยเพื่อนก่อนที่การแก้ไขจะปรากฏให้เห็น)
Duncan Babbage

คำตอบ:


125

คุณต้องตั้งค่าcontentSizeคุณสมบัติของไฟล์UIScrollView. ตัวอย่างเช่นหากคุณUIScrollViewกว้าง 320 พิกเซล (ความกว้างของหน้าจอ) คุณสามารถทำได้:

CGSize scrollableSize = CGSizeMake(320, myScrollableHeight);
[myScrollView setContentSize:scrollableSize];

UIScrollViewจะแล้วเท่านั้นเลื่อนแนวตั้งเพราะมันสามารถอยู่แล้วแสดงทุกอย่างในแนวนอน


6
สวัสดี. วิธีนี้ใช้งานได้ดีจริงๆ! ขอบคุณสำหรับสิ่งนั้น ฉันลองตั้งค่าความกว้างคงที่เป็น 0 สำหรับฉันมันก็ใช้ได้เช่นกัน ฉันไม่รู้ว่าอาจมีผลข้างเคียงในภายหลังหรือไม่ แต่ถ้าใครไม่ทราบขนาด (เช่นรหัสสากลสำหรับ iPhone และ iPad) ก็ใช้งานได้ดี!
JackPearse

5
ฉันคิดว่าดีกว่าที่จะทำ CGSizeMake (0, myScrollableHeight) ดังนั้นการเลื่อนแนวนอนจึงปิดใช้งานแม้ว่าจะไม่ได้แสดงมุมมองย่อยทั้งหมดก็ตาม
LightNight

NB การตั้งค่าหนึ่งในมิติข้อมูลเป็น 0 เมื่อใช้การเพจจะทำให้ VoiceOver ประกาศหมายเลขหน้าเป็น "หน้าที่ 1 จาก 1" โดยไม่คำนึงถึงค่าที่ถูกต้อง
josef

1
แทนที่จะส่งความกว้างเป็น 320 ฮาร์ดโค้ดเราสามารถส่งผ่านเช่น: CGSize scrollableSize = CGSizeMake (self.scrollview.frame.size.width, myScrollableHeight); [myScrollView setContentSize: scrollableSize];
Mohit kumar

91

ปรับปรุง: (หลังจากที่ @EranMarom ชี้ให้เห็นในความคิดเห็นของเขา)

คุณสามารถหยุดการเลื่อนแนวนอนหรือการเลื่อนแนวตั้งในScrollViewDelegateวิธีการ นี่คือวิธีการ

หยุดการเลื่อนแนวนอน:

หากคุณต้องการเลื่อนในแนวนอนคุณต้องเพิ่ม contentOffset.x การป้องกันนั้นจะหยุดการเลื่อนมุมมองในแนวนอน

- (void)scrollViewDidScroll:(UIScrollView *)sender {
    sender.contentOffset.x = 0.0
}

หยุดการเลื่อนแนวตั้ง:

หากคุณต้องการเลื่อนในแนวตั้งคุณต้องเพิ่ม contentOffset.y การป้องกันนั้นจะหยุดการเลื่อนมุมมองในแนวตั้ง

- (void)scrollViewDidScroll:(UIScrollView *)sender {
    sender.contentOffset.y = 0.0
}

โค้ดด้านบนป้องกันการเปลี่ยนแปลงในxและyของ a scrollview contentOffsetและนำไปสู่การหยุดการเลื่อนในscrollViewDidScroll:วิธีการ


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

14
นี่เป็นการแฮ็ก แต่จะใช้ได้ผลเมื่อทุกอย่างล้มเหลว +1 แต่ใช้เป็นทางเลือกสุดท้ายเท่านั้น
i_am_jorf

5
ฉันยังใช้วิธีการมอบหมายนี้ แต่ฉันแทนที่ร่างกายด้วยซับในเช่น: scrollView.contentOffset = CGPointMake(0, scrollView.contentOffset.y);เพื่อปิดใช้งานการเลื่อนแนวนอน ฉันพบว่ามันอ่านได้ง่ายขึ้นมันเล็กลงและไม่มีจุดใดที่จะทำการทดสอบให้เป็นศูนย์เพราะแทบจะไม่มีค่าใช้จ่ายใด ๆ กับโค้ดที่รันสิ่งนี้ไม่บ่อยนัก (เช่นสูงสุดไม่กี่สิบครั้งต่อวินาที)
Echelon

เนื่องจากคุณกำลังเปลี่ยน contentOffset หลังจาก "didscroll" ไม่ใช่เหมือนก่อน "willscroll" และนี่เป็นวิธีแก้ปัญหาด้วยค้อน แต่ตัวฉันเองไม่ได้โหวตลงคะแนนเพราะ 18 โหวตและคำตอบคือ 75 ดังนั้นจึงไม่สมควรที่จะลดคะแนน
LolaRun

2
ใช้scrollView.contentOffset.y = 0.0เพื่อหยุดการเลื่อนแนวตั้งและscrollView.contentOffset.x = 0.0หยุดการเลื่อนในแนวนอนได้ง่ายยิ่งขึ้นในscrollViewDidScroll()ฟังก์ชันมอบหมาย อย่างไรก็ตามฉันเชื่อว่าการตรวจสอบให้แน่ใจว่าscrollView.contentSizeเท่ากับscrollView.frame.sizeเป็นการแก้ปัญหาที่ดีกว่า (ถูกต้อง) ดูคำตอบของ @danbeaulieu
emem

11

ตั้งแต่ใช้ iOS7

self.automaticallyAdjustsScrollViewInsets = NO;

// และสร้างตัวเลื่อนหน้าของคุณด้วย 3 หน้า

    self.pageView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
    [self.pageView setContentSize:CGSizeMake(self.view.frame.size.width*3, self.view.frame.size.height)];
    [self.pageView setShowsVerticalScrollIndicator:NO];
    [self.pageView setPagingEnabled:YES];
    [self.view addSubview:self.pageView];

ฉันไม่คิดว่าสิ่งนี้จะปิดใช้งานพฤติกรรมการเลื่อนของ scrollview ใช่ไหม??
Dinesh Raja

self.collectionView.pagingEnabled = YES;ช่วยฉันแก้ปัญหาด้วยการเลื่อนอย่างราบรื่น (ไม่ลาก) ปัญหาอยู่ในวิธีการscrollViewWillEndDragging:- targetContentOffset เหมือนกับ scrollView.contentOffset และตรรกะการตรวจจับหน้าทำงานไม่ถูกต้อง
sig

11

โซลูชันที่รวดเร็ว

สร้างสองร้านหนึ่งสำหรับมุมมองของคุณและอีกหนึ่งสำหรับมุมมองแบบเลื่อนของคุณ:

@IBOutlet weak var myView: UIView!
@IBOutlet weak var scrollView: UIScrollView!

จากนั้นใน viewDidLayoutSubviews ของคุณคุณสามารถเพิ่มรหัสต่อไปนี้:

let scrollSize = CGSize(width: myView.frame.size.width, 
                        height: myView.frame.size.height)
scrollView.contentSize = scrollSize

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


ความคิดเพิ่มเติม:

CGSizeMake ใช้ความกว้างและความสูงโดยใช้ CGFloats คุณอาจต้องใช้ความสูงที่มีอยู่ UIScrollViews ของคุณสำหรับพารามิเตอร์ที่สอง ซึ่งจะมีลักษณะดังนี้:

let scrollSize = CGSize(width: myView.frame.size.width, 
                        height: scrollView.contentSize.height)

จะเกิดอะไรขึ้นถ้าคุณไม่ทราบความสูงหรือความกว้าง (อุปกรณ์สากล)? @danbeaulieu
Lukesivi

@lukesIvi "myView.frame.width" กำลังดึงความกว้างจาก IBOutlet "myView" แบบไดนามิก
Dan Beaulieu

4

ในกรณีของฉันกับSwift 4.2 คุณสามารถใช้:

ปิดใช้งานการเลื่อนแนวตั้ง:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    scrollView.contentOffset.y = 0.0
}

ปิดใช้งานการเลื่อนแนวนอน:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    scrollView.contentOffset.x = 0.0
}


3

ในกรณีของฉันความกว้างของ contentView มากกว่าความกว้างของ UIScrollView และนั่นคือสาเหตุของการเลื่อนแนวนอนที่ไม่ต้องการ ฉันแก้ไขโดยตั้งค่าความกว้างของ contentView ให้เท่ากับความกว้างของ UIScrollView

หวังว่ามันจะช่วยใครบางคน


@Nostradamus ยินดีให้ความช่วยเหลือ
Gulfam Khan

0

ฉันมี tableview contentInset ที่ตั้งไว้ใน viewDidLoad (ตามด้านล่าง) ว่าอะไรทำให้เกิดการเลื่อนแนวนอน

self.tableView.contentInset = UIEdgeInsetsMake(0, 30, 0, 0);

ตรวจสอบว่ามีการตั้งค่า tableview contentInset ด้วยเหตุผลอื่นหรือไม่และปิดใช้งาน


0

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

อย่างไรก็ตามในเธรดอื่น (ไม่แน่ใจว่าที่ไหน) มีคนแนะนำว่าการใช้ข้อ จำกัด เชิงลบบน UIScrollView ได้ผลสำหรับเขา

ดังนั้นฉันจึงลองใช้ข้อ จำกัด ที่หลากหลายซึ่งได้ผลลัพธ์ที่ไม่สอดคล้องกัน ในที่สุดสิ่งที่ได้ผลสำหรับฉันคือการเพิ่มข้อ จำกัด ที่นำหน้าและต่อท้าย -32 ไปยังมุมมองแบบเลื่อนและเพิ่มมุมมองข้อความ (มองไม่เห็น) ที่มีความกว้าง 320 (และอยู่กึ่งกลาง)


0

ลองสิ่งนี้:

CGSize scrollSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, scrollHeight);
[scrollView setContentSize: scrollSize];

0

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

override var contentOffset: CGPoint {
  get {
    return super.contentOffset
  }
  set {
    super.contentOffset = CGPoint(x: 0, y: newValue.y)
  }
}

0

แนะนำใน iOS 11 เป็นคุณสมบัติใหม่บน UIScrollView

var contentLayoutGuide: UILayoutGuide

เอกสารระบุว่าคุณ:

ใช้คำแนะนำเค้าโครงนี้เมื่อคุณต้องการสร้างข้อ จำกัด ของเค้าโครงอัตโนมัติที่เกี่ยวข้องกับพื้นที่เนื้อหาของมุมมองแบบเลื่อน

พร้อมกับข้อ จำกัด autolayout อื่น ๆ ที่คุณอาจจะมีการเพิ่มคุณจะต้องเป็นการบังคับwidthAnchorของUIScrollView's contentLayoutGuideจะเป็นขนาดเดียวกับ 'กรอบ' คุณสามารถใช้frameLayoutGuide(แนะนำใน iOS 11) หรือความกว้างภายนอกใดก็ได้ (เช่นของคุณsuperView)

ตัวอย่าง:

NSLayoutConstraint.activate([
  scrollView.contentLayoutGuide.widthAnchor.constraint(equalTo: self.widthAnchor)
])

เอกสารประกอบ: https://developer.apple.com/documentation/uikit/uiscrollview/2865870-contentlayoutguide



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