Mar*_*ady 66 uitableview uiscrollview uikit uipageviewcontroller swift
我需要做这个有奇怪配置的应用程序.
如下图所示,主视图是UIScrollView.然后里面应该有一个UIPageView,而PageView的每个页面都应该有一个UITableView.
到目前为止我已经完成了这一切.但我的问题是我希望滚动行为 自然.
接下来是我的意思自然.目前,当我滚动其中一个UITableViews时,它会滚动tableview(而不是scrollview).但我希望它滚动ScrollView,除非scrollview无法滚动导致它到达顶部或底部(在这种情况下,我希望它滚动tableview).
例如,假设我的滚动视图当前滚动到顶部.然后我把手指放在桌面视图(显示的当前页面)上并开始向下滚动.在这种情况下,我希望滚动视图滚动(没有tableview).如果我继续向下滚动我的滚动视图并且它到达底部,如果我从显示器上移开手指并将其放回tebleview并再次向下滚动,我希望我的tableview现在向下滚动,因为滚动视图到达底部并且它不是能够继续滚动.
你们对如何实现这种滚动有任何想法吗?
我真的迷失了.任何帮助将非常感激它:(
谢谢!
Dan*_*ang 52
同时处理滚动视图和表视图的解决方案围绕着UIScrollViewDelegate.因此,让您的视图控制器符合该协议:
class ViewController: UIViewController, UIScrollViewDelegate {
Run Code Online (Sandbox Code Playgroud)
我将滚动视图和表视图表示为插座:
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var tableView: UITableView!
Run Code Online (Sandbox Code Playgroud)
我们还需要跟踪滚动视图内容的高度以及屏幕高度.你以后会明白为什么.
let screenHeight = UIScreen.mainScreen().bounds.height
let scrollViewContentHeight = 1200 as CGFloat
Run Code Online (Sandbox Code Playgroud)
需要一点配置viewDidLoad::
override func viewDidLoad() {
super.viewDidLoad()
scrollView.contentSize = CGSizeMake(scrollViewContentWidth, scrollViewContentHeight)
scrollView.delegate = self
tableView.delegate = self
scrollView.bounces = false
tableView.bounces = false
tableView.scrollEnabled = false
}
Run Code Online (Sandbox Code Playgroud)
在那里我关掉了弹跳以保持简单.键设置是滚动视图和表视图的委托,并且首先关闭表视图滚动.
这些是必需的,以便scrollViewDidScroll:委托方法可以处理到达滚动视图的底部并到达表视图的顶部.这是方法:
func scrollViewDidScroll(scrollView: UIScrollView) {
let yOffset = scrollView.contentOffset.y
if scrollView == self.scrollView {
if yOffset >= scrollViewContentHeight - screenHeight {
scrollView.scrollEnabled = false
tableView.scrollEnabled = true
}
}
if scrollView == self.tableView {
if yOffset <= 0 {
self.scrollView.scrollEnabled = true
self.tableView.scrollEnabled = false
}
}
}
Run Code Online (Sandbox Code Playgroud)
委托方法正在做的是检测滚动视图何时到达其底部.发生这种情况时,可以滚动表视图.它还检测表视图何时到达重新启用滚动视图的顶部.
我创建了一个GIF来演示结果:
小智 21
修改Daniel的答案,使其更高效,无bug.
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var tableHeight: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
//Set table height to cover entire view
//if navigation bar is not translucent, reduce navigation bar height from view height
tableHeight.constant = self.view.frame.height-64
self.tableView.isScrollEnabled = false
//no need to write following if checked in storyboard
self.scrollView.bounces = false
self.tableView.bounces = true
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 20
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let label = UILabel(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 30))
label.text = "Section 1"
label.textAlignment = .center
label.backgroundColor = .yellow
return label
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = "Row: \(indexPath.row+1)"
return cell
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView == self.scrollView {
tableView.isScrollEnabled = (self.scrollView.contentOffset.y >= 200)
}
if scrollView == self.tableView {
self.tableView.isScrollEnabled = (tableView.contentOffset.y > 0)
}
}
Run Code Online (Sandbox Code Playgroud)
完整的项目可以在这里看到:https: //gitlab.com/vineetks/TableScroll.git
小智 5
经过多次试验和错误,这对我来说是最有效的。该解决方案必须解决两个需求:1)确定应使用谁的滚动属性;tableView或scrollView?2)确保tableView在到达其表/内容的顶部之前,不向scrollView授予权限。
为了查看是否应该使用scrollview进行滚动而不是使用tableview,我检查了tableview上方的UIView是否在框架内。如果UIView在框架内,可以肯定地说scrollView应该有权滚动。如果UIView不在框架内,则意味着tableView占据了整个窗口,因此应该有权滚动。
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.bounds.intersects(UIView.frame) == true {
//the UIView is within frame, use the UIScrollView's scrolling.
if tableView.contentOffset.y == 0 {
//tableViews content is at the top of the tableView.
tableView.isUserInteractionEnabled = false
tableView.resignFirstResponder()
print("using scrollView scroll")
} else {
//UIView is in frame, but the tableView still has more content to scroll before resigning its scrolling over to ScrollView.
tableView.isUserInteractionEnabled = true
scrollView.resignFirstResponder()
print("using tableView scroll")
}
} else {
//UIView is not in frame. Use tableViews scroll.
tableView.isUserInteractionEnabled = true
scrollView.resignFirstResponder()
print("using tableView scroll")
}
}
Run Code Online (Sandbox Code Playgroud)
希望这对某人有帮助!
小智 5
如果您遇到嵌套滚动问题,这是最简单的解决方案。
我认为有两种选择。
由于您知道滚动视图和主视图的大小,因此您无法判断滚动视图是否到达底部。
if (scrollView.contentOffset.y >= (scrollView.contentSize.height - scrollView.frame.size.height)) {
// reach bottom
}
Run Code Online (Sandbox Code Playgroud)
所以当它击中时;你基本上设定
[contentScrollView setScrollEnabled:NO];
Run Code Online (Sandbox Code Playgroud)
以及您的 tableView 的其他方式。
另一件事,我认为更准确,是将手势添加到您的视图中。
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(respondToTapGesture:)];
// Specify that the gesture must be a single tap
tapRecognizer.numberOfTapsRequired = 1;
// Add the tap gesture recognizer to the view
[self.view addGestureRecognizer:tapRecognizer];
// Do any additional setup after loading the view, typically from a nib
Run Code Online (Sandbox Code Playgroud)
因此,当您添加手势时,您可以通过setScrollEnabled更改respondToTapGesture.
| 归档时间: |
|
| 查看次数: |
49780 次 |
| 最近记录: |