案例:https://github.com/ArtworkAD/ios_jumping_y.git
容器
class ContainerController: UIViewController {
@IBOutlet weak var container: UIView!
@IBOutlet weak var foregroundTopSpace: NSLayoutConstraint!
@IBOutlet weak var foregroundBottomSpace: NSLayoutConstraint!
}
容器连接到右侧的UITableViewController。
我想做什么
用户滚动桌子,当他到达顶部时,我想以相同的动作向下移动桌子。所以我只需更改容器视图的顶部/底部空间。但是这会导致表跳转。
class MainController: UITableViewController, UIGestureRecognizerDelegate {
var panRecognizer: UIPanGestureRecognizer!
var gotStart: Bool = true
var startTouch: CGPoint!
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.bounces = false
self.panRecognizer = self.tableView.panGestureRecognizer
self.panRecognizer.addTarget(self, action: "pan:")
self.tableView.addGestureRecognizer(self.panRecognizer)
}
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
func pan(rec:UIPanGestureRecognizer){
if let parent = self.parentViewController as? ContainerController {
var y = self.tableView.contentOffset.y
var touch = rec.locationInView(self.view)
// JUMPING y
println(touch.y)
if y == -64 {
if self.gotStart || y < -64 || y > -64 {
self.startTouch = touch
self.gotStart = false
} else {
if rec.state == .Changed {
var changedVerticalHeight = (self.startTouch.y - touch.y)*(-1)
if changedVerticalHeight <= parent.view.frame.size.height && touch.y >= changedVerticalHeight {
parent.foregroundTopSpace.constant = changedVerticalHeight
parent.foregroundBottomSpace.constant = -changedVerticalHeight
}
} else if rec.state == .Ended {
parent.foregroundTopSpace.constant = 0
parent.foregroundBottomSpace.constant = 0
self.gotStart = true
}
}
}
}
}
}
结果:
任何想法都错了吗?容器视图必须有一些问题,因为当我直接移动表视图时,没有跳跃。
答案 0 :(得分:3)
在我提出完整的代码
之前,我将在答案中澄清一些事情您可以使用scrollViewWillEndDragging
函数来了解contentOffset
的确切位置,请参阅以下代码:
override func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
println(targetContentOffset.memory.y)
}
您可以使用函数scrollViewDidEndDecelerating
知道滚动完成的时间。
然后,您可以合并上述两个提示,以便通过以下方式实现目标:
class MainController: UITableViewController {
var position : CGFloat!
override func viewDidLoad() {
super.viewDidLoad()
}
override func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
// Save where the contentOffset go
position = targetContentOffset.memory.y
}
override func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
// If reach the top or more than the top when the user move the scroll
if (position < 0) {
var to = scrollView.contentOffset.y + 213
scrollView.setContentOffset(CGPoint(x: 0, y: to), animated: true)
}
}
// Default table stuff, not related to problem
/* Here comes the rest of your code of TableView */
}
我删除了与panGestureRecognizer
相关的项目代码,然后跳出来进行测试。
在var to = scrollView.contentOffset.y + 213
行中,您可以添加position
变量或所需的值,我只会213
来测试向下移动。
我希望这对你有所帮助。
答案 1 :(得分:1)
您从self.view
系统坐标打印位置。 UITableViewController
使用像self.view这样的表格视图。因此,当用户滚动时,原点(x:0 y:0)开始移动。
您必须使用静态系统坐标。正确使用UIViewController
和UITableView
panGestureRecognizer
属性打印位置并进行滚动:
UIViewController
。UITableview
并设置AutoLayout
。IBOutlet
与UITableView
将代码添加到UIViewController
类:
var panRecognizer: UIPanGestureRecognizer!
@IBOutlet weak var tableView: UITableView?
override func viewDidLoad() {
super.viewDidLoad()
self.panRecognizer = tableView?.panGestureRecognizer;
self.panRecognizer .addTarget(self, action: "pan:")
tableView?.addGestureRecognizer(self.panRecognizer)
}
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
func pan(rec:UIPanGestureRecognizer){
println(rec.locationInView(self.view).y)
}
您可以下载项目示例here。
如果您只需要控制滚动,请记住UIScrollView delegate method:
optional func scrollViewDidScroll(_ scrollView: UIScrollView)
可以帮到你。它是一个更简洁的解决方案:
祝你好运。答案 2 :(得分:0)
我完全相信你想要的东西:
import UIKit
class MainController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
let beginingContentOffset: CGFloat = -64
if scrollView.contentOffset.y < beginingContentOffset {
scrollView.bounces = false
UIView.animateWithDuration(0.05, animations: { () -> Void in
scrollView.contentOffset = CGPointMake(0, 0)
}, completion: { (finished: Bool) -> Void in
scrollView.bounces = true
})
}
}
// Default table stuff, not related to problem
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 20
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell_ : UITableViewCell? = tableView.dequeueReusableCellWithIdentifier("CELL_ID") as? UITableViewCell
if(cell_ == nil){
cell_ = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "CELL_ID")
}
cell_!.textLabel!.text = "Row " + String(indexPath.row)
return cell_!
}
}
P.S。那&#34; -64&#34;值。它是故事板的边缘。您可以取消选中约束的边距,它将是&#34; 0&#34;。这将是非常清楚的