IOS快速扩展视图

时间:2014-07-29 11:31:55

标签: ios swift expandable

我想在将开关切换到开启时展开视图,在将开关切换到关闭时展开。 与此同时,我设计中的所有其他元素都必须向下或向上移动。

以下是开关 OFF

时布局的样子

以下是开关 ON 时的布局:

我希望你明白我要做的事。

问题是......我该怎么办?

3 个答案:

答案 0 :(得分:4)

使用AutoLayout和InterfaceBuilder(使用xib或storyboard)更容易,所以如果需要,最重要的是熟悉它们。

  1. 围绕UISwitches包裹容器UIView,并确保将其设置为Clip Subviews
  2. 为容器视图的高度添加约束并将其设置为0.
  3. 将该约束拖到类声明中以生成IBOutlet属性。
  4. 从UISwitch拖动新的插座' Value Changed'将事件发送给类以生成IBAction方法。
  5. 确保实现该方法,以便在值更改时,根据更改切换动画高度约束(IBOutlet)

    self.firstHeightConstraint.constant = on ? 200.0 : 0.0
    self.view.setNeedsUpdateConstraints()
    UIView.animateWithDuration( ... 
        options:.BeginFromCurrentState, 
        animations: { self.view.layoutIfNeeded() } ...
    )
    

答案 1 :(得分:1)

使用UIView,这不是一个好方法。您应该使用UITableView而不是视图。

使用TableView,您可以在UITableView的标题中根据第一张图片添加带有标题的UISwitch,并在状态为ON的情况下在TableView的更改部分中返回所需的行数,并在状态为OFF时返回行数0。

还有问题,请让我知道,我会帮助您。

答案 2 :(得分:0)

enter image description here

我知道我的代码不是最干净的,但是当答案告诉提问者这不是一个好方法或这样做时,它让我烦恼。我提供了一个不使用表视图或约束的解决方案:

在您的示例中,您可以为需要移动的每个“级别”使用标签。因此,从开关 2 和其下的所有视图开始,您将拥有该级别的标签(第二个隐藏的可折叠视图也将具有标签 2),然后开关 3 将具有标签 3。

对于隐藏的标签,您将它们添加到我称为 insideView1 或 insideView2 的子视图中。那些内部视图的框架应该具有适当的 minX、minY 和宽度,但开始时的高度为 0。同样重要的是,它们有 layer.masksToBounds = false,所以当它们的高度为 0 时,它们的子视图不会显示。然后我们将高度更改为适当的高度(展开),以及改变位置的所有子视图。

最后,我制作了一个字典来跟踪某个部分何时展开,以便您可以使用相同的功能来展开/折叠已经展开的其他区域。

import UIKit

class ExpandViewController: UIViewController {

    var insideView1 = UIView()
    var insideView2 = UIView()
    var expand = [1:true,2:true]
    
    @objc func expandCollapse(_ sender : UIButton) {
        var heightChange = CGFloat(0)
        switch sender.tag {
        case 1:
            heightChange = 90
        default:
            heightChange = 90
        }

        var viewsToExpand = [UIView(),insideView1,insideView2]
        
        UIView.animate(withDuration: 1.0) { [self] in
            let expandMe = viewsToExpand[sender.tag]
            if expand[sender.tag] == true {
                expandMe.frame.size.height = heightChange
                for v in view.subviews {
                    if v.tag > sender.tag {
                        v.center.y += heightChange
                    }
                }
            } else {
                expandMe.frame.size.height = 0
                for v in view.subviews {
                    if v.tag > sender.tag {
                        v.center.y -= heightChange
                    }
                }
            }
            expand[sender.tag] = !expand[sender.tag]!
        }
    }
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
     
        let switcher1 = UISwitch()
        switcher1.tag = 1
        switcher1.isOn = false
        switcher1.frame = CGRect(x: view.bounds.width - 150, y: 100, width: 40, height: 30)
        switcher1.addTarget(self, action: #selector(expandCollapse(_:)), for: .allTouchEvents)
        view.addSubview(switcher1)
        let switchLabel1 = UILabel()
        switchLabel1.tag = 1
        switchLabel1.text = "Switch 1"
        switchLabel1.frame = CGRect(x: 30, y: 0, width: view.bounds.width, height: 30)
        switchLabel1.center.y = switcher1.center.y
        view.addSubview(switchLabel1)
        
        let switcher2 = UISwitch()
        switcher2.tag = 2
        switcher2.isOn = false
        switcher2.frame = CGRect(x: view.bounds.width - 150, y: 140, width: 40, height: 30)
        switcher2.addTarget(self, action: #selector(expandCollapse(_:)), for: .allTouchEvents)
        view.addSubview(switcher2)
        let switchLabel2 = UILabel()
        switchLabel2.tag = 2
        switchLabel2.text = "Switch 2"
        switchLabel2.frame = CGRect(x: 30, y: 0, width: view.bounds.width, height: 30)
        switchLabel2.center.y = switcher2.center.y
        view.addSubview(switchLabel2)
        
        let switcher3 = UISwitch()
        switcher3.tag = 3
        switcher3.isOn = false
        switcher3.frame = CGRect(x: view.bounds.width - 150, y: 180, width: 40, height: 30)
//        switcher3.addTarget(self, action: #selector(expandCollapse(_:)), for: .allTouchEvents)
        view.addSubview(switcher3)
        let switchLabel3 = UILabel()
        switchLabel3.tag = 3
        switchLabel3.text = "Switch 3"
        switchLabel3.frame = CGRect(x: 30, y: 0, width: view.bounds.width, height: 30)
        switchLabel3.center.y = switcher3.center.y
        view.addSubview(switchLabel3)
        
        insideView1.frame = CGRect(x: 0, y: switcher1.frame.maxY + 5, width: view.bounds.width, height: 0)
        insideView1.layer.backgroundColor = UIColor.lightGray.cgColor
        insideView1.layer.masksToBounds = true
        insideView1.tag = 1
        view.addSubview(insideView1)
        
        insideView2.frame = CGRect(x: 0, y: switcher2.frame.maxY + 5, width: view.bounds.width, height: 0)
        insideView2.layer.backgroundColor = UIColor.lightGray.cgColor
        insideView2.layer.masksToBounds = true
        insideView2.tag = 2
        view.addSubview(insideView2)
        
        let insideLabel1 = UILabel()
        insideLabel1.text = "Label"
        insideLabel1.frame = CGRect(x: 60, y: 10, width: view.bounds.width, height: 30)
        insideView1.addSubview(insideLabel1)
        let insideTextField1 = UITextField()
        insideTextField1.frame = CGRect(x: 200, y: 0, width: view.bounds.width - 240, height: 30)
        insideTextField1.center.y = insideLabel1.center.y
        insideTextField1.layer.backgroundColor = UIColor.white.cgColor
        insideView1.addSubview(insideTextField1)
        
        let insideLabel2 = UILabel()
        insideLabel2.text = "Label"
        insideLabel2.frame = CGRect(x: 60, y: 50, width: view.bounds.width, height: 30)
        insideView1.addSubview(insideLabel2)
        let insideTextField2 = UITextField()
        insideTextField2.frame = CGRect(x: 200, y: 0, width: view.bounds.width - 240, height: 30)
        insideTextField2.center.y = insideLabel2.center.y
        insideTextField2.layer.backgroundColor = UIColor.white.cgColor
        insideView1.addSubview(insideTextField2)
        
        let insideLabel3 = UILabel()
        insideLabel3.text = "Label"
        insideLabel3.frame = CGRect(x: 60, y: 10, width: view.bounds.width, height: 30)
        insideView2.addSubview(insideLabel3)
        let insideTextField3 = UITextField()
        insideTextField3.frame = CGRect(x: 200, y: 0, width: view.bounds.width - 240, height: 30)
        insideTextField3.center.y = insideLabel3.center.y
        insideTextField3.layer.backgroundColor = UIColor.white.cgColor
        insideView2.addSubview(insideTextField3)
        
        let insideLabel4 = UILabel()
        insideLabel4.text = "Label"
        insideLabel4.frame = CGRect(x: 60, y: 50, width: view.bounds.width, height: 30)
        insideView2.addSubview(insideLabel4)
        let insideTextField4 = UITextField()
        insideTextField4.frame = CGRect(x: 200, y: 0, width: view.bounds.width - 240, height: 30)
        insideTextField4.center.y = insideLabel4.center.y
        insideTextField4.layer.backgroundColor = UIColor.white.cgColor
        insideView2.addSubview(insideTextField4)
    }
}