我想在将开关切换到开启时展开视图,在将开关切换到关闭时展开。 与此同时,我设计中的所有其他元素都必须向下或向上移动。
以下是开关 OFF
时布局的样子
以下是开关 ON 时的布局:
我希望你明白我要做的事。
问题是......我该怎么办?
答案 0 :(得分:4)
使用AutoLayout和InterfaceBuilder(使用xib或storyboard)更容易,所以如果需要,最重要的是熟悉它们。
Clip Subviews
。确保实现该方法,以便在值更改时,根据更改切换动画高度约束(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)
我知道我的代码不是最干净的,但是当答案告诉提问者这不是一个好方法或这样做时,它让我烦恼。我提供了一个不使用表视图或约束的解决方案:
在您的示例中,您可以为需要移动的每个“级别”使用标签。因此,从开关 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)
}
}