Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/104.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS内容通过动画从水平到垂直,反之亦然_Ios_Swift_Uistackview - Fatal编程技术网

iOS内容通过动画从水平到垂直,反之亦然

iOS内容通过动画从水平到垂直,反之亦然,ios,swift,uistackview,Ios,Swift,Uistackview,我们能否通过UIStackView实现这一点,因为最初它的垂直轴,然后最终它将是水平轴,反之亦然 如果使用NSAutoLayout,如何做到这一点 需要帮助,如果有人可以提供我的例子来源或任何提示在这里将是有益的 更新答案 多亏了@Fogmeister 首先,我做两个堆栈视图 一个保持命名和配置文件图像 和bigStackView保持第一个stackView和后续按钮 像这样的约束 BigStackView: 我之所以在左、右各加20分,是因为如果我将其设为0,则“跟随”按钮将接近屏幕边缘

我们能否通过
UIStackView
实现这一点,因为最初它的垂直轴,然后最终它将是水平轴,反之亦然

如果使用
NSAutoLayout
,如何做到这一点

需要帮助,如果有人可以提供我的例子来源或任何提示在这里将是有益的


更新答案

多亏了@Fogmeister

首先,我做两个堆栈视图 一个保持命名和配置文件图像

和bigStackView保持第一个stackView和后续按钮

像这样的约束

BigStackView:

我之所以在左、右各加20分,是因为如果我将其设为0,则“跟随”按钮将接近屏幕边缘

堆栈视图: 您不需要在此stackView上添加约束

档案图像:

可命名:

以下图片:

然后我在向下滚动时,使它们的间距相等,为5

但当向上滚动时,StackView的间距将为15,因此纵断面图像将远远无法命名(这就是我添加两个StackView以便控制间距的原因)

并将高度约束添加到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
        }
    }







}
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
        }
    }







}
结果是


我希望此解决方案适用于您

更新答案

多亏了@Fogmeister

首先,我做两个堆栈视图 一个保持命名和配置文件图像

和bigStackView保持第一个stackView和后续按钮

像这样的约束

BigStackView:

我之所以在左、右各加20分,是因为如果我将其设为0,则“跟随”按钮将接近屏幕边缘

堆栈视图: 您不需要在此stackView上添加约束

档案图像:

可命名:

以下图片:

然后我在向下滚动时,使它们的间距相等,为5

但当向上滚动时,StackView的间距将为15,因此纵断面图像将远远无法命名(这就是我添加两个StackView以便控制间距的原因)

并将高度约束添加到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
        }
    }







}
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
        }
    }







}
结果是


我希望这个解决方案对您来说是常见的

我想我应该使用
UIStackView
添加一个答案,因为您似乎没有尝试就放弃了它

我在这里添加了所有代码的要点。这个代码有点狡猾,因为95%的代码都在设置操场页面和视图等

总共花了我大约10分钟

看着你的动画,我注意到只有三件事在改变。圆形视图的大小、圆形视图的角半径以及布局的轴(垂直/水平)

这反映在我的示例中使用的动画代码中

UIView.animate(withDuration: 0.5) {
    stackView.axis = .horizontal
    roundViewHeightConstraint.constant = 60
    roundView.layer.cornerRadius = 30
}
这将导致以下动画(可以调整以改进它,但我没有太多时间来编写此动画)

稍微更新了代码以尝试改进动画

stackView.axis = .horizontal
roundViewHeightConstraint.constant = 60

UIView.animate(withDuration: 0.5) {
    containerView.layoutIfNeeded()
}
新动画。。。


角半径不能在层上正确设置动画。这是因为我使用的是UIView,而不是像您原来使用的UIImageView。使用UIImageView,您不会像我这样费心更改角半径。只需使用圆形图像即可。

我想我应该使用
UIStackView
添加一个答案,因为您似乎没有尝试就忽略了它

我在这里添加了所有代码的要点。这个代码有点狡猾,因为95%的代码都在设置操场页面和视图等

总共花了我大约10分钟

看着你的动画,我注意到只有三件事在改变。圆形视图的大小、圆形视图的角半径以及布局的轴(垂直/水平)

这反映在我的示例中使用的动画代码中

UIView.animate(withDuration: 0.5) {
    stackView.axis = .horizontal
    roundViewHeightConstraint.constant = 60
    roundView.layer.cornerRadius = 30
}
这将导致以下动画(可以调整以改进它,但我没有太多时间来编写此动画)

稍微更新了代码以尝试改进动画

stackView.axis = .horizontal
roundViewHeightConstraint.constant = 60

UIView.animate(withDuration: 0.5) {
    containerView.layoutIfNeeded()
}
新动画。。。


角半径不能在层上正确设置动画。这是因为我使用的是UIView,而不是像您原来使用的UIImageView。使用UIImageView,您不会像我这样费心更改角半径。只需使用圆形图像即可。

检查此@JonSnow:这里我的要求更复杂。但我想说谢谢你的提示+1因为我认为UIStackView在这里没有帮助,我可以通过动画观察水平轴的大小变化显然,你什么都不知道@JonSnow<代码>UIStackViews执行帮助,请参阅下面的答案。(没有冒犯,没有私事,必须这么做)@JonSnow。。。伙计。去看《权力的游戏》。看看这个@JonSnow:这里我的要求更复杂。但我想说谢谢你的提示+1因为我认为UIStackView在这里没有帮助,我可以通过动画观察水平轴的大小变化显然,你什么都不知道@JonSnow<代码>UIStackViews执行帮助,请参阅下面的答案。(没有冒犯,没有私事,必须这么做)@JonSnow。。。伙计。去看《权力的游戏》。这在StackView中是可能的。这实际上就是设置
轴的动画的情况。一行代码。(好吧,也许几句话)我觉得很可笑,人们总是说“我需要这个,为我做吧”,而你每天的常规任务最多只需要30分钟。你的约束是否正在打破,如果你不介意的话,可以给我看看你的申请公司吗