ฉันมีUIView
สปริงบอร์ดเหมือน iPhone ฉันได้สร้างมันขึ้นมาโดยใช้UIScrollView
และUIButtons
. ฉันต้องการปิดการใช้งานการเลื่อนแนวนอนใน scrollview ดังกล่าว ฉันต้องการเพียงการเลื่อนในแนวตั้ง ฉันจะทำสิ่งนี้ให้สำเร็จได้อย่างไร?
ฉันมีUIView
สปริงบอร์ดเหมือน iPhone ฉันได้สร้างมันขึ้นมาโดยใช้UIScrollView
และUIButtons
. ฉันต้องการปิดการใช้งานการเลื่อนแนวนอนใน scrollview ดังกล่าว ฉันต้องการเพียงการเลื่อนในแนวตั้ง ฉันจะทำสิ่งนี้ให้สำเร็จได้อย่างไร?
คำตอบ:
คุณต้องตั้งค่าcontentSize
คุณสมบัติของไฟล์UIScrollView
. ตัวอย่างเช่นหากคุณUIScrollView
กว้าง 320 พิกเซล (ความกว้างของหน้าจอ) คุณสามารถทำได้:
CGSize scrollableSize = CGSizeMake(320, myScrollableHeight);
[myScrollView setContentSize:scrollableSize];
UIScrollView
จะแล้วเท่านั้นเลื่อนแนวตั้งเพราะมันสามารถอยู่แล้วแสดงทุกอย่างในแนวนอน
ปรับปรุง: (หลังจากที่ @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:
วิธีการ
scrollView.contentOffset = CGPointMake(0, scrollView.contentOffset.y);
เพื่อปิดใช้งานการเลื่อนแนวนอน ฉันพบว่ามันอ่านได้ง่ายขึ้นมันเล็กลงและไม่มีจุดใดที่จะทำการทดสอบให้เป็นศูนย์เพราะแทบจะไม่มีค่าใช้จ่ายใด ๆ กับโค้ดที่รันสิ่งนี้ไม่บ่อยนัก (เช่นสูงสุดไม่กี่สิบครั้งต่อวินาที)
scrollView.contentOffset.y = 0.0
เพื่อหยุดการเลื่อนแนวตั้งและscrollView.contentOffset.x = 0.0
หยุดการเลื่อนในแนวนอนได้ง่ายยิ่งขึ้นในscrollViewDidScroll()
ฟังก์ชันมอบหมาย อย่างไรก็ตามฉันเชื่อว่าการตรวจสอบให้แน่ใจว่าscrollView.contentSize
เท่ากับscrollView.frame.size
เป็นการแก้ปัญหาที่ดีกว่า (ถูกต้อง) ดูคำตอบของ @danbeaulieu
ตั้งแต่ใช้ 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];
self.collectionView.pagingEnabled = YES;
ช่วยฉันแก้ปัญหาด้วยการเลื่อนอย่างราบรื่น (ไม่ลาก) ปัญหาอยู่ในวิธีการscrollViewWillEndDragging:
- targetContentOffset เหมือนกับ scrollView.contentOffset และตรรกะการตรวจจับหน้าทำงานไม่ถูกต้อง
โซลูชันที่รวดเร็ว
สร้างสองร้านหนึ่งสำหรับมุมมองของคุณและอีกหนึ่งสำหรับมุมมองแบบเลื่อนของคุณ:
@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)
ในกรณีของฉันกับSwift 4.2 คุณสามารถใช้:
ปิดใช้งานการเลื่อนแนวตั้ง:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
scrollView.contentOffset.y = 0.0
}
ปิดใช้งานการเลื่อนแนวนอน:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
scrollView.contentOffset.x = 0.0
}
คุณสามารถเลือกมุมมองแล้วภายใต้การยกเลิกAttributes Inspector
User Interaction Enabled
ในกรณีของฉันความกว้างของ contentView มากกว่าความกว้างของ UIScrollView และนั่นคือสาเหตุของการเลื่อนแนวนอนที่ไม่ต้องการ ฉันแก้ไขโดยตั้งค่าความกว้างของ contentView ให้เท่ากับความกว้างของ UIScrollView
หวังว่ามันจะช่วยใครบางคน
ฉันมี tableview contentInset ที่ตั้งไว้ใน viewDidLoad (ตามด้านล่าง) ว่าอะไรทำให้เกิดการเลื่อนแนวนอน
self.tableView.contentInset = UIEdgeInsetsMake(0, 30, 0, 0);
ตรวจสอบว่ามีการตั้งค่า tableview contentInset ด้วยเหตุผลอื่นหรือไม่และปิดใช้งาน
ฉันต่อสู้กับสิ่งนี้มาระยะหนึ่งแล้วพยายามทำตามคำแนะนำต่างๆในกระทู้นี้และหัวข้ออื่น ๆ ไม่สำเร็จ
อย่างไรก็ตามในเธรดอื่น (ไม่แน่ใจว่าที่ไหน) มีคนแนะนำว่าการใช้ข้อ จำกัด เชิงลบบน UIScrollView ได้ผลสำหรับเขา
ดังนั้นฉันจึงลองใช้ข้อ จำกัด ที่หลากหลายซึ่งได้ผลลัพธ์ที่ไม่สอดคล้องกัน ในที่สุดสิ่งที่ได้ผลสำหรับฉันคือการเพิ่มข้อ จำกัด ที่นำหน้าและต่อท้าย -32 ไปยังมุมมองแบบเลื่อนและเพิ่มมุมมองข้อความ (มองไม่เห็น) ที่มีความกว้าง 320 (และอยู่กึ่งกลาง)
ลองสิ่งนี้:
CGSize scrollSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, scrollHeight);
[scrollView setContentSize: scrollSize];
ปิดใช้งานการเลื่อนแนวนอนโดยการแทนที่contentOffset
คุณสมบัติในคลาสย่อย
override var contentOffset: CGPoint {
get {
return super.contentOffset
}
set {
super.contentOffset = CGPoint(x: 0, y: newValue.y)
}
}
แนะนำใน 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
เมื่อฉันเปลี่ยน UIScrollView ด้วย UITableView ด้วยเซลล์เพียง 1 เซลล์มันก็ใช้ได้ดี
ใช้บรรทัดเดียวนี้
self.automaticallyAdjustsScrollViewInsets = NO;