ded*_*ded 17 uitableview ios parallax swift
我正在使用Swift在iOS 8.4中构建一个应用程序.
我有一个包含a 和UITableView
的自定义.这一切都相当直接,一切都很好.UITableViewCell
UILabel
UIImageView
我正在尝试创建一个类似于此演示中演示的视差效果.
我目前在我的代码中有这个代码 tableView.cellForRowAtIndexPath
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = self.tableView.dequeueReusableCellWithIdentifier("myitem", forIndexPath: indexPath) as! MixTableViewCell
cell.img.backgroundColor = UIColor.blackColor()
cell.title.text = self.items[indexPath.row]["title"]
cell.img.image = UIImage(named: "Example.png")
// ideally it would be cool to have an extension allowing the following
// cell.img.addParallax(50) // or some other configurable offset
return cell
}
Run Code Online (Sandbox Code Playgroud)
该块存在于类似的类中 class HomeController: UIViewController, UITableViewDelegate, UITableViewDataSource { ... }
我也知道我可以通过我的班级听滚动事件func scrollViewDidScroll
.
除此之外,感谢帮助!
ded*_*ded 32
我想到了!我们的想法是在不实现任何额外库的情况下执行此操作,特别是考虑到实现的简单性.
首先......在自定义表视图Cell
类中,您必须创建一个包装器视图.您可以UIImageView
在Prototype单元格中选择,然后选择Editor > Embed in > View
.将两个拖动到单元格作为出口,然后设置clipToBounds = true
为包含视图.(还记得将约束设置为与图像相同.
class MyCustomCell: UITableViewCell {
@IBOutlet weak var img: UIImageView!
@IBOutlet weak var imgWrapper: UIView!
override func awakeFromNib() {
self.imgWrapper.clipsToBounds = true
}
}
Run Code Online (Sandbox Code Playgroud)
然后在你的UITableViewController
子类(或委托)中,实现scrollViewDidScroll
- 从这里你将不断更新UIImageView
的.frame
属性.见下文:
override func scrollViewDidScroll(scrollView: UIScrollView) {
let offsetY = self.tableView.contentOffset.y
for cell in self.tableView.visibleCells as! [MyCustomCell] {
let x = cell.img.frame.origin.x
let w = cell.img.bounds.width
let h = cell.img.bounds.height
let y = ((offsetY - cell.frame.origin.y) / h) * 25
cell.img.frame = CGRectMake(x, y, w, h)
}
}
Run Code Online (Sandbox Code Playgroud)
Nyc*_*cen 25
我对@ded的解决方案不太满意,需要一个包装器视图,所以我想出了另一个使用自动布局的解决方案,并且非常简单.
在故事板中,您只需添加imageView并在ImageView上设置4个约束:
最后两个约束(顶部和高度)需要引用自定义UITableViewCell的出口(在上面的图片中,双击最右边列中的约束,然后显示连接检查器 - 图标是圆圈中的箭头)
您的UITableViewCell应该如下所示:
class ParallaxTableViewCell: UITableViewCell {
@IBOutlet weak var parallaxImageView: UIImageView!
// MARK: ParallaxCell
@IBOutlet weak var parallaxHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var parallaxTopConstraint: NSLayoutConstraint!
override func awakeFromNib() {
super.awakeFromNib()
clipsToBounds = true
parallaxImageView.contentMode = .ScaleAspectFill
parallaxImageView.clipsToBounds = false
}
}
Run Code Online (Sandbox Code Playgroud)
所以基本上,我们告诉图像尽可能多地占用空间,但我们将其剪切到单元格框架.
现在你的TableViewController看起来像这样:
class ParallaxTableViewController: UITableViewController {
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return cellHeight
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("CellIdentifier", forIndexPath: indexPath) as! ParallaxTableViewCell
cell.parallaxImageView.image = … // Set your image
cell.parallaxHeightConstraint.constant = parallaxImageHeight
cell.parallaxTopConstraint.constant = parallaxOffsetFor(tableView.contentOffset.y, cell: cell)
return cell
}
// Change the ratio or enter a fixed value, whatever you need
var cellHeight: CGFloat {
return tableView.frame.width * 9 / 16
}
// Just an alias to make the code easier to read
var imageVisibleHeight: CGFloat {
return cellHeight
}
// Change this value to whatever you like (it sets how "fast" the image moves when you scroll)
let parallaxOffsetSpeed: CGFloat = 25
// This just makes sure that whatever the design is, there's enough image to be displayed, I let it up to you to figure out the details, but it's not a magic formula don't worry :)
var parallaxImageHeight: CGFloat {
let maxOffset = (sqrt(pow(cellHeight, 2) + 4 * parallaxOffsetSpeed * tableView.frame.height) - cellHeight) / 2
return imageVisibleHeight + maxOffset
}
// Used when the table dequeues a cell, or when it scrolls
func parallaxOffsetFor(newOffsetY: CGFloat, cell: UITableViewCell) -> CGFloat {
return ((newOffsetY - cell.frame.origin.y) / parallaxImageHeight) * parallaxOffsetSpeed
}
override func scrollViewDidScroll(scrollView: UIScrollView) {
let offsetY = tableView.contentOffset.y
for cell in tableView.visibleCells as! [MyCustomTableViewCell] {
cell.parallaxTopConstraint.constant = parallaxOffsetFor(offsetY, cell: cell)
}
}
}
Run Code Online (Sandbox Code Playgroud)
笔记:
所以你有它,parallax UITableViewCells应该适用于任何布局,也可以适应CollectionViews.
归档时间: |
|
查看次数: |
16649 次 |
最近记录: |