gpt4 book ai didi

ios - 当 SuperViews 约束更改时更新 subview 约束

转载 作者:行者123 更新时间:2023-11-30 11:21:43 25 4
gpt4 key购买 nike

我有一个位于 UITableView 之上的 UIView (如屏幕截图所示)。当用户滚动 UITableView 时,我将 UIView 移出屏幕(从顶部)。 UIView 可以正确移动,但 UIView 内的项目保持在其位置。我怎样才能移动它们?

P.S:我从下面的帖子中得到了帮助,并感谢它的发布者:),也对很多代码感到抱歉,但我无法决定如何缩小它。

https://github.com/MichiganLabs/AnimatingTableViewHeader

编辑:我通过将所有约束添加到同一 View 而犯了错误,我修复了该问题,但问题仍然出现。

    override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.view.backgroundColor = UIColor.white
setupUI()

}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.headerHeightConstraint.constant = self.maxHeaderHeight
updateHeader()
}

private func setupUI(){
self.view.backgroundColor = UIColor.white
self.tableView.delegate = self
self.tableView.dataSource = self
self.headerView.backgroundColor = Color.Common.welcomeScreenBackgroundColor.withAlphaComponent(0.5)
self.view.addSubview(tableView)
self.view.addSubview(headerView)
headerView.translatesAutoresizingMaskIntoConstraints = false
tableView.translatesAutoresizingMaskIntoConstraints = false
//cityBtn.translatesAutoresizingMaskIntoConstraints = false
cityLbl.text = "İL"
headerView.addSubview(cityLbl)
headerView.addSubview(cityBtn)


//Header = 20 from left edge of screen
let cn1 = NSLayoutConstraint(item: headerView, attribute: .leading, relatedBy: .equal, toItem: self.view, attribute: .leading, multiplier: 1.0, constant: 20)
//Header view trailing end is 20 px from right edge of the screen
let cn2 = NSLayoutConstraint(item: headerView, attribute: .trailing, relatedBy: .equal, toItem: self.view, attribute: .trailing, multiplier: 1.0, constant: -20)
let cn3 = NSLayoutConstraint(item: headerView, attribute: .bottom, relatedBy: .equal, toItem: self.tableView, attribute: .top, multiplier: 1.0, constant: -20)
//Header view height = constant 240
headerHeightConstraint = NSLayoutConstraint(item: headerView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant:230)
//Header view vertical padding from the top edge of the screen = 20
let topConstraint = NSLayoutConstraint(item: headerView, attribute: .top, relatedBy: .equal, toItem: self.topLayoutGuide, attribute: .bottom, multiplier: 1.0, constant: 20)

//Header = 20 from left edge of screen
let tb1 = NSLayoutConstraint(item: tableView, attribute: .leading, relatedBy: .equal, toItem: self.view, attribute: .leading, multiplier: 1.0, constant: 0)
//Header view trailing end is 20 px from right edge of the screen
let tb2 = NSLayoutConstraint(item: tableView, attribute: .trailing, relatedBy: .equal, toItem: self.view, attribute: .trailing, multiplier: 1.0, constant: 0)
let tb3 = NSLayoutConstraint(item: tableView, attribute: .bottom, relatedBy: .equal, toItem: self.view, attribute: .bottom, multiplier: 1.0, constant: 0)
let tb4 = NSLayoutConstraint(item: tableView, attribute: .top, relatedBy: .equal, toItem: self.headerView, attribute: .bottom, multiplier: 1.0, constant: 0)


//Header view trailing end is 20 px from right edge of the screen
let cb1 = NSLayoutConstraint(item: cityBtn, attribute: .width, relatedBy: .equal, toItem: self.headerView, attribute: .width, multiplier: 0.6, constant: 0)
let cb2 = NSLayoutConstraint(item: cityBtn, attribute: .trailing, relatedBy: .equal, toItem: self.headerView, attribute: .trailing, multiplier: 1.0, constant: -20)
cityBtnTopConstraint = NSLayoutConstraint(item: cityBtn, attribute: .top, relatedBy: .equal, toItem: self.headerView, attribute: .top, multiplier: 1.0, constant: 20)
let cb4 = NSLayoutConstraint(item: cityBtn, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant:50)

self.view.addConstraints([cn1,cn2,cn3,headerHeightConstraint,topConstraint,tb1,tb2,tb3,tb4])
self.headerView.addConstraints([cb1,cb2,cityBtnTopConstraint,cb4])

}
override func viewDidLayoutSubviews() {
cityLbl.leftAnchor.constraint(equalTo: headerView.leftAnchor, constant: 20).isActive = true
cityLbl.centerYAnchor.constraint(equalTo: cityBtn.centerYAnchor).isActive = true
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let scrollDiff = scrollView.contentOffset.y - self.previousScrollOffset

let absoluteTop: CGFloat = 0;
let absoluteBottom: CGFloat = scrollView.contentSize.height - scrollView.frame.size.height;

let isScrollingDown = scrollDiff > 0 && scrollView.contentOffset.y > absoluteTop
let isScrollingUp = scrollDiff < 0 && scrollView.contentOffset.y < absoluteBottom

if canAnimateHeader(scrollView) {

// Calculate new header height
var newHeight = self.headerHeightConstraint.constant
if isScrollingDown {
newHeight = max(self.minHeaderHeight, self.headerHeightConstraint.constant - abs(scrollDiff))
} else if isScrollingUp {
newHeight = min(self.maxHeaderHeight, self.headerHeightConstraint.constant + abs(scrollDiff))
}

// Header needs to animate
if newHeight != self.headerHeightConstraint.constant {
self.headerHeightConstraint.constant = newHeight
self.updateHeader()
self.setScrollPosition(self.previousScrollOffset)
}

self.previousScrollOffset = scrollView.contentOffset.y
}
}

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
self.scrollViewDidStopScrolling()
}

func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
if !decelerate {
self.scrollViewDidStopScrolling()
}
}

func scrollViewDidStopScrolling() {
let range = self.maxHeaderHeight - self.minHeaderHeight
let midPoint = self.minHeaderHeight + (range / 2)

if self.headerHeightConstraint.constant > midPoint {
self.expandHeader()
} else {
self.collapseHeader()
}
}

func canAnimateHeader(_ scrollView: UIScrollView) -> Bool {
// Calculate the size of the scrollView when header is collapsed
let scrollViewMaxHeight = scrollView.frame.height + self.headerHeightConstraint.constant - minHeaderHeight

// Make sure that when header is collapsed, there is still room to scroll
return scrollView.contentSize.height > scrollViewMaxHeight
}

func collapseHeader() {
self.view.layoutIfNeeded()
UIView.animate(withDuration: 0.2, animations: {
self.headerHeightConstraint.constant = self.minHeaderHeight
self.updateHeader()
self.view.layoutIfNeeded()
})
}

func expandHeader() {
self.view.layoutIfNeeded()
UIView.animate(withDuration: 0.2, animations: {
self.headerHeightConstraint.constant = self.maxHeaderHeight
self.updateHeader()
self.view.layoutIfNeeded()
})
}

func setScrollPosition(_ position: CGFloat) {
self.tableView.contentOffset = CGPoint(x: self.tableView.contentOffset.x, y: position)
}

func updateHeader() {
let range = self.maxHeaderHeight - self.minHeaderHeight
let openAmount = self.headerHeightConstraint.constant - self.minHeaderHeight
let percentage = openAmount / range

self.cityBtn.alpha = percentage
//self.titleTopConstraint.constant = -openAmount + 10
//self.logoImageView.alpha = percentage
}

最佳答案

问题是您将所有约束添加到 self.view 中,您需要在 headerView 及其 subview 之间添加约束到 headerView ,因此将其拆分

self.view.addConstraints([cn1,cn2,cn3,headerHeightConstraint,topConstraint,tb1,tb2,  tb3,tb4,cb1,cb2,cityBtnTopConstraint,cb4])

self.view.addConstraints([cn1,cn2,cn3,headerHeightConstraint,topConstraint,tb1,tb2,  tb3,tb4])

&&

headerView.addConstraints([cb1,cb2,cityBtnTopConstraint,cb4])

关于ios - 当 SuperViews 约束更改时更新 subview 约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51190693/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com