iOS动画– UIScrollView内的UIStackView

We have already discussed through examples and implemented UIStackView in a tutorial before. In this tutorial, we’ll learn how to add a UIStackView inside a UIScrollView and also implement adding and removing views from a UIStackView programmatically and animate them.

之前,我们已经通过示例进行了讨论并实现了UIStackView 。 在本教程中,我们将学习如何在UIScrollView内添加UIStackView以及如何以编程方式实现从UIStackView添加和删除视图以及对其进行动画处理。

UIScrollView内的UIStackView (UIStackView inside UIScrollView)

Following are the steps you need to follow in order to add a UIStackView inside a UIScrollView.

以下是您需要执行的步骤,以便在UIScrollView中添加UIStackView。

  • Add the UIScrollView to the View Controller View and set the constraints to all the sides of the View.

    将UIScrollView添加到视图控制器视图,并将约束设置到视图的所有侧面。
  • Add a UIStackView inside the UIScrollView. Set the constraints: Leading, Trailing, Top & Bottom to the ScrollView.

    在UIScrollView内添加一个UIStackView。 设置约束:ScrollView的前导,尾随,顶部和底部。
  • If the StackView is to be scrolled Vertically, set an Equal Width Constraint between the UIStackView and the UIScrollView.

    如果StackView要垂直滚动,请在UIStackView和UIScrollView之间设置等宽约束。
  • If the StackView is to be scrolled Horizontally, set an Equal Height Constraint between the UIStackView and the UIScrollView.

    如果要水平滚动StackView,请在UIStackView和UIScrollView之间设置等高约束。
  • Add your SubViews inside the UIStackView and enjoy scrolling.

    在UIStackView内添加SubViews并享受滚动。

Let’s demonstrate this in our XCode Project Main.storyboard.

让我们在XCode Project Main.storyboard

Now let’s add a few Buttons inside the StackView:

现在让我们在StackView中添加一些按钮:

The output in the simulator is given below:

ios uistackview uiscrollview output

模拟器中的输出如下:

Let’s look at building a UIStackView programmatically next.

接下来,让我们看看以编程方式构建UIStackView。

UIStackView以编程方式 (UIStackView programmatically)

Open up your ViewController.swift file and add the following lines of code:

打开您的ViewController.swift文件,并添加以下代码行:

import UIKit

class ViewController: UIViewController {

    
    var stackView = UIStackView()
    var constraintBottom : NSLayoutConstraint?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        let textField = UITextField()
        textField.placeholder = "Email"
        textField.textColor = UIColor.darkGray
        textField.minimumFontSize = 17.0
        textField.borderStyle = UITextField.BorderStyle.roundedRect
        textField.keyboardType = UIKeyboardType.emailAddress
        textField.returnKeyType = UIReturnKeyType.next
        
        
        let textFieldPassword = UITextField()
        textFieldPassword.placeholder = "Password"
        textFieldPassword.textColor = UIColor.darkGray
        textFieldPassword.minimumFontSize = 17.0
        textFieldPassword.textAlignment = .right
        textFieldPassword.isSecureTextEntry = true
        textFieldPassword.borderStyle = UITextField.BorderStyle.roundedRect
        textFieldPassword.keyboardType = UIKeyboardType.default
        textFieldPassword.returnKeyType = UIReturnKeyType.done
        
        
        let button = UIButton(type: UIButton.ButtonType.system)
        button.setTitle("Login", for: UIControl.State.normal)
        button.setTitleColor(UIColor.white, for: UIControl.State.normal)
        button.backgroundColor = UIColor.black
        button.layer.borderColor = UIColor.white.cgColor
        button.layer.borderWidth = 1.0
        button.layer.cornerRadius = 5.0
        button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
        button.tag = 1
        
        
        stackView = UIStackView(arrangedSubviews: [textField, textFieldPassword, button])
        stackView.axis = .vertical
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.distribution = .fillEqually
        stackView.alignment = .fill
        stackView.spacing = 20.0
        
        view.addSubview(stackView)

        stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20).isActive = true
        stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20).isActive = true
        stackView.topAnchor.constraint(equalTo: view.topAnchor, constant: 40).isActive = true
        constraintBottom = stackView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -40)
        constraintBottom?.isActive = true
        
    }
    
    @objc func buttonAction(sender: UIButton!) {
        
            if(sender.tag == 1){
            constraintBottom?.isActive = false
            stackView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -100).isActive = true
            }
    }


}

In this code, we’ve set UITextField and Buttons inside a UIStackView vertically which are filled equally. We set the constraints on the stackView using NSLayoutConstraint.

在这段代码中,我们在UIStackView中垂直设置了UITextField和Buttons,它们被均等地填充。 我们使用NSLayoutConstraint在stackView上设置约束。

The subViews are passed in the arrangeSubView array. On Button click, we set a selector to disable the bottom constraint of the StackView and add a new one which increases the bottom margin.

子视图在ArrangeSubView数组中传递。 单击“按钮”时,我们设置了一个选择器以禁用StackView的底部约束,并添加一个新的选择器以增加底部边距。

translatesAutoresizingMaskIntoConstraints must be set to false since UIStackViews use Auto-layouts.

因为UIStackViews使用自动布局,所以translatesAutoresizingMaskIntoConstraints必须设置为false。

isHidden property is used to toggle the visibility of a complete StackView including all it’s elements.
isHidden属性用于切换包括其所有元素的完整StackView的可见性。

使用功能加载子视图 (Loading SubViews using Function)

Instead of passing individual subViews in the array, we can populate the UIStackView using a function as shown below:

我们可以使用如下所示的函数填充UIStackView,而不是在数组中传递单个subViews:

class ViewController: UIViewController {

    
    var stackView = UIStackView()
    var constraintBottom : NSLayoutConstraint?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        
        stackView = UIStackView(arrangedSubviews: createButtonArray(named: "1","2","3","4"))
        

        stackView.axis = .vertical
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.distribution = .fillEqually
        stackView.alignment = .fill
        stackView.spacing = 20.0

        view.addSubview(stackView)

        stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20).isActive = true
        stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20).isActive = true
        stackView.topAnchor.constraint(equalTo: view.topAnchor, constant: 40).isActive = true
        constraintBottom = stackView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -40)
        constraintBottom?.isActive = true
        
    }

    
    func createButtonArray(named: String...) -> [UIButton]
    {
        return named.map{name in
            let button  = UIButton()
            button.translatesAutoresizingMaskIntoConstraints = false
            button.setTitle("Button \(name)", for: .normal)
            button.backgroundColor = UIColor.red
            button.setTitleColor(UIColor.white, for: .normal)
            return button
        }
    }
}

createButtonArray creates an array by transforming the strings into their corresponding Button instances to compose the array.

createButtonArray通过将字符串转换为相应的Button实例以构成数组来创建数组。

单击添加子视图 (Adding SubViews On Click)

Let’s configure each of the above Buttons to add another subView on button click. We will be adding a nested subview.

让我们配置上述每个按钮,以在单击按钮时添加另一个subView。 我们将添加一个嵌套的子视图。

The viewDidLoad method remains the same as before. The other methods in the ViewController.swift are:

viewDidLoad方法与以前相同。 ViewController.swift中的其他方法是:

func createButtonArray(named: String...) -> [UIButton]
    {
        return named.map{name in
            let button  = UIButton()
            button.translatesAutoresizingMaskIntoConstraints = false
            button.setTitle("Button \(name)", for: .normal)
            button.backgroundColor = UIColor.red
            button.setTitleColor(UIColor.white, for: .normal)
            button.tag = named.firstIndex(of: name)!
            button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
            return button
        }
    }
    
    @objc func buttonAction(sender: UIButton!) {
            print("Button tag is")
            print(sender.tag)
            createNestedSubView(sender.tag)
    }
    
    func createNestedSubView(_ tag: Int)
    {
        let ss = UIStackView(arrangedSubviews: createButtonArray(named: "\(tag+1).1","\(tag+1).2","\(tag+1).3","\(tag+1).4"))
        
        
        ss.axis = .horizontal
        ss.translatesAutoresizingMaskIntoConstraints = false
        ss.distribution = .fillEqually
        ss.alignment = .fill
        ss.spacing = 5.0
        
        stackView.insertArrangedSubview(ss, at: tag)
        
        ss.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20).isActive = true
        ss.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20).isActive = true
        ss.heightAnchor.constraint(equalToConstant: 50.0).isActive = true
    }

Thus, on button click, we pass the index of the button. A nested horizontal StackView is created.
The new stack view is inserted at the tag number index.

因此,在单击按钮时,我们传递按钮的索引。 将创建一个嵌套的水平StackView。
新的堆栈视图将插入标签编号索引处。

insertArrangedSubview is used to insert the SubView in the UIStackView at a certain index.

insertArrangedSubview用于在某个索引处将SubView插入UIStackView中。

arrangeSubView is used to insert the new SubView at the end of the UIStackView.

arrangeSubView用于在UIStackView的末尾插入新的SubView。

以编程方式删除SubView (Removing SubViews Programmatically)

We can remove the SubViews using the function removeArrangedSubview on the UIStackView instance.
Also, we need to remove the view from the SuperView too.

我们可以使用UIStackView实例上的removeArrangedSubview函数删除SubView。
另外,我们也需要从SuperView中删除该视图。

In the ViewController.swift createButtonArray function we add another button click action for the nested StackView buttons. When any of them are clicked they would be deleted:

在ViewController.swift createButtonArray函数中,我们为嵌套的StackView按钮添加了另一个按钮单击操作。 单击其中任何一个时,它们将被删除:

func createButtonArray(named: String...) -> [UIButton]
    {
        return named.map{name in
            let button  = UIButton()
            button.translatesAutoresizingMaskIntoConstraints = false
            button.setTitle("Button \(name)", for: .normal)
            button.backgroundColor = UIColor.red
            button.setTitleColor(UIColor.white, for: .normal)
            button.tag = named.firstIndex(of: name)!
            if(name.contains("."))
            {
            button.addTarget(self, action: #selector(deleteAction), for: .touchUpInside)
            }
            else{
            button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
            }
            return button
        }
    }

 @objc func deleteAction(sender: UIButton!) {
        print("Delete tag is")
        print(sender.titleLabel?.text! ?? "NA")
        stackView.removeArrangedSubview(sender)
        sender.removeFromSuperview()
        
    }

The output of the application in action is given below:

ios uistackview programmatically removing sub views

实际应用程序的输出如下:

动画子视图 (Animating SubViews)

We can animate the subViews when the isHidden property is toggled using:

当使用以下方法切换isHidden属性时,我们可以为subViews设置动画:

UIView.animate(withDuration: 0.5){
                    button.isHidden = true //or false
                }

In the above application, we hide and animate the Button 4 when it is clicked:

在上面的应用程序中,当单击按钮4时,我们将其隐藏并设置动画:

@objc func buttonAction(sender: UIButton!) {
            print("Button tag is")
            print(sender.tag)
        
            if(sender.titleLabel?.text?.contains("4"))!
            {
                UIView.animate(withDuration: 0.5){
                    sender.isHidden = true //or false
                }
            }
        
            createNestedSubView(sender.tag)
    }

This brings an end to this tutorial. You can download the project from the link below:

本教程到此结束。 您可以从下面的链接下载项目:

翻译自: https://www.journaldev.com/22088/ios-animation-uistackview-views-uiscrollview

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值