Обновите ограничения SubView при изменении ограничений SuperViews - PullRequest
0 голосов
/ 05 июля 2018

У меня есть UIView, который находится над UITableView (как видно на скриншоте). Я перемещаю UIView из экрана (сверху), когда пользователь прокручивает UITableView. UIView может правильно перемещаться, но предметы внутри этого UIView остаются на своих местах. Как я могу также переместить их?

P.S .: Я получил помощь из поста ниже и благодаря его издателю :), а также извините за большое количество кода, но я не могу решить, как его минимизировать.

https://github.com/MichiganLabs/AnimatingTableViewHeader

РЕДАКТИРОВАТЬ: я делал ошибку, добавляя все ограничения в то же представление, я исправил это, но проблема все еще возникает.

    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
}

1 Ответ

0 голосов
/ 05 июля 2018

Проблема в том, что вы добавляете все ограничения к self.view, вам нужно добавить ограничения между headerView и его подпредставлениями к 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])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...