更新答案
感谢@Fogmeister
首先,我创建两个堆栈视图
和bigStackView保持第一个stackView和followButton
像这样的约束
我之所以在左右两侧添加20个点,是因为如果我将其设置为0,则“跟随”按钮将接近屏幕边缘!
堆栈视图:
您不需要在此堆栈视图上添加约束
可命名:
下图:
并为stackView添加160点的高约束
向上滚动时将其更改为100点
代码将变成这样
import UIKit
class ViewController: UIViewController , UITableViewDelegate , UITableViewDataSource {
@IBOutlet weak var bigStackView: UIStackView!
@IBOutlet weak var StackView: UIStackView!
@IBOutlet weak var StackViewHight: NSLayoutConstraint!
@IBOutlet weak var progileHight: NSLayoutConstraint!
@IBOutlet weak var profileWidth: NSLayoutConstraint!
var rowsNames = ["Row 0", "Row 1", "Row 2", "Row 3", "Row 4", "Row 5",
"Row 6", "Row 7", "Row 8", "Row 9", "Row 10", "Row 11",
"Row 12", "Row 13", "Row 14", "Row 15", "Row 16", "Row 17",
"Row 18", "Row 19", "Row 20", "Row 21", "Row 22", "Row 23",
"Row 24", "Row 25", "Row 26", "Row 27", "Row 28", "Row 29", "Row 20"]
// we set a variable to hold the contentOffSet before scroll view scrolls
var lastContentOffset: CGFloat = 0
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - UITableViewDataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return rowsNames.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = rowsNames[indexPath.row]
return cell
}
// this delegate is called when the scrollView (i.e your UITableView) will start scrolling
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
self.lastContentOffset = scrollView.contentOffset.y
}
// while scrolling this delegate is being called so you may now check which direction your scrollView is being scrolled to
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if (self.lastContentOffset < scrollView.contentOffset.y) {
// moved to top
UIView.animate(withDuration: 0.5,
animations: {
// Change Hight and Witdh of profileImage (make it smaller)
self.progileHight.constant = 50
self.profileWidth.constant = 50
self.bigStackView.axis = .horizontal
self.StackView.axis = .horizontal
// Change spacing between profileImage and nameLable
self.StackView.spacing = 15
// Make BigStackView Smaller
self.StackViewHight.constant = 100
self.view.layoutIfNeeded()
})
} else if (self.lastContentOffset > scrollView.contentOffset.y) {
// moved to bottom
UIView.animate(withDuration: 0.5,
animations: {
// return Hight and Witdh of profileImage to its orginal size
self.progileHight.constant = 100
self.profileWidth.constant = 100
self.bigStackView.axis = .vertical
self.StackView.axis = .vertical
// return spacing between profileImage and nameLable to the orginal space
self.StackView.spacing = 5
// return BigStackView to its orginal size
self.StackViewHight.constant = 160
self.view.layoutIfNeeded()
})
} else {
// didn't move
}
}
}
结果将是:
我不认为你能通过UIStackView实现这一点
但使用UIView很容易做到这一点
UIView:
配置文件图像:
以下按钮:
我在每台iPhone设备上都做了测试,在iPad上,这种限制并没有打破
然后你只需要使用UIView。使有生气
移动物品
import UIKit
class ViewController: UIViewController , UITableViewDelegate , UITableViewDataSource {
var rowsNames = ["Row 0", "Row 1", "Row 2", "Row 3", "Row 4", "Row 5",
"Row 6", "Row 7", "Row 8", "Row 9", "Row 10", "Row 11",
"Row 12", "Row 13", "Row 14", "Row 15", "Row 16", "Row 17",
"Row 18", "Row 19", "Row 20", "Row 21", "Row 22", "Row 23",
"Row 24", "Row 25", "Row 26", "Row 27", "Row 28", "Row 29", "Row 20"]
@IBOutlet weak var squareView: UIView!
@IBOutlet weak var hightView: NSLayoutConstraint!
@IBOutlet weak var profileImage: UIImageView!
@IBOutlet weak var followButton: UIButton!
@IBOutlet weak var nameLable: UILabel!
// we set a variable to hold the contentOffSet before scroll view scrolls
var lastContentOffset: CGFloat = 0
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - UITableViewDataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return rowsNames.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = rowsNames[indexPath.row]
return cell
}
// this delegate is called when the scrollView (i.e your UITableView) will start scrolling
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
self.lastContentOffset = scrollView.contentOffset.y
}
// while scrolling this delegate is being called so you may now check which direction your scrollView is being scrolled to
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if (self.lastContentOffset < scrollView.contentOffset.y) {
// moved to top
self.hightView.constant = 100
UIView.animate(withDuration: 0.5,
animations: {
self.profileImage.transform = CGAffineTransform(translationX:-150, y: -15).scaledBy(x: 0.5, y: 0.5)
self.followButton.transform = CGAffineTransform(translationX:130, y: -110)
self.nameLable.transform = CGAffineTransform(translationX:-95, y: -80)
self.view.layoutIfNeeded()
})
} else if (self.lastContentOffset > scrollView.contentOffset.y) {
// moved to bottom
UIView.animate(withDuration: 0.5,
animations: {
self.hightView.constant = 206
self.profileImage.transform = CGAffineTransform.identity
self.followButton.transform = CGAffineTransform.identity
self.nameLable.transform = CGAffineTransform.identity
self.view.layoutIfNeeded()
})
} else {
// didn't move
}
}
}
我所做的是检测用户是否向上或向下滚动
我改变了UIView的高度
更改ProfileImage的位置并将其缩小一半
然后更改namaLable和followButton
我将高尺寸还原为原始尺寸
并使用将其余视图恢复为其原始大小
CGAffineTransform.identity
结果是