我有三个UIButton
,我已经创建了编程约束,在某些情况下我将UIButton
中的一个删除为button.removeFromSuperview()
&其余两个按钮将根据优先级设置约束。
问题是当我删除一个UIButton
(buttonWink)然后从viewLifeCycle viewWillLayoutSubviews
开始调用&应用程序崩溃在下面的行
buttonWink.translatesAutoresizingMaskIntoConstraints = false
当然因为buttonWink已从superview中删除,但我们可以在设置约束之前检查
if buttonWink != nil {
buttonWink.translatesAutoresizingMaskIntoConstraints = false
}
但是通过检查每个按钮的nil会使代码冗长,有没有办法做同样的事情?我真的很感谢朋友。
输出 -
这里我附上了我尝试过的完整代码。
import UIKit
class MasterViewController: UIViewController {
@IBOutlet weak var buttonMessage : UIButton!
@IBOutlet weak var buttonLike : UIButton!
@IBOutlet weak var buttonWink : UIButton!
@IBAction func tapsOnLike(_ sender: UIButton) {
sender.removeFromSuperview()
}
@IBAction func tapsOnWink(_ sender: UIButton) {
sender.removeFromSuperview()
}
@IBAction func tapsOnNextButton(){
let vc = DetailViewController(nibName: "DetailViewController", bundle: nil)
navigationController?.pushViewController(vc, animated: true)
}
override func viewDidLoad() {
super.viewDidLoad()
setConstraints()
navigationController?.isNavigationBarHidden = true
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
// setConstraints()
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
//setConstraints()
}
func setConstraints() {
if buttonMessage != nil {
buttonMessage?.translatesAutoresizingMaskIntoConstraints = false
}
buttonLike?.translatesAutoresizingMaskIntoConstraints = false
buttonWink?.translatesAutoresizingMaskIntoConstraints = false
//Constraints for Message button
let leading = NSLayoutConstraint(item: buttonMessage, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1.0, constant: 8)
leading.isActive = true
let trailingToSuperView = NSLayoutConstraint(item: buttonMessage, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1, constant: -8)
trailingToSuperView.priority = 998
trailingToSuperView.isActive = true
let bottomToSuperView = NSLayoutConstraint(item: buttonMessage, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: -8)
bottomToSuperView.isActive = true
let trailingToWink = NSLayoutConstraint(item: buttonMessage, attribute: .trailing, relatedBy: .equal, toItem: buttonWink, attribute: .leading, multiplier: 1, constant: -8)
trailingToWink.priority = 999
trailingToWink.isActive = true
let leadingToLike = NSLayoutConstraint(item: buttonMessage, attribute: .trailing, relatedBy: .equal, toItem: buttonLike, attribute: .leading, multiplier: 1.0, constant: -8)
leadingToLike.isActive = true
let alignBottomToWink = NSLayoutConstraint(item: buttonMessage, attribute: .bottom, relatedBy: .equal, toItem: buttonWink, attribute: .bottom, multiplier: 1, constant: 0)
alignBottomToWink.isActive = true
let alignBottomToLike = NSLayoutConstraint(item: buttonMessage, attribute: .bottom, relatedBy: .equal, toItem: buttonLike, attribute: .bottom, multiplier: 1, constant: 0)
alignBottomToLike.isActive = true
let equalWidthToWink = NSLayoutConstraint(item: buttonMessage, attribute: .width, relatedBy: .equal, toItem: buttonWink, attribute: .width, multiplier: 1, constant: 0)
equalWidthToWink.isActive = true
let equalWidthToLike = NSLayoutConstraint(item: buttonMessage, attribute: .width, relatedBy: .equal, toItem: buttonLike, attribute: .width, multiplier: 1, constant: 0)
equalWidthToLike.isActive = true
//Constraints for like button
let trailingLikeToSuperView = NSLayoutConstraint(item: buttonLike, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1, constant: -8)
trailingLikeToSuperView.priority = 999
trailingLikeToSuperView.isActive = true
let leadingToWink = NSLayoutConstraint(item: buttonLike, attribute: .trailing, relatedBy: .equal, toItem: buttonWink, attribute: .leading, multiplier: 1.0, constant: -8)
leadingToWink.isActive = true
//Constraints for Wink button
let trailingWinkToSuperView = NSLayoutConstraint(item: buttonWink, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1, constant: -8)
trailingWinkToSuperView.isActive = true
}
}
答案 0 :(得分:4)
仅供参考 -
只需使用堆栈视图即可。
这非常容易:这就是为什么Apple最近几年前添加了一个堆栈概念。
答案 1 :(得分:1)
我刚刚添加了UIStackView
&这很容易
在水平堆叠视图中添加了三个按钮,具有8个点间距&添加了三个约束来将视图堆叠为leading
,trailing
& bottom
至superview
@IBOutlet weak var stackView: UIStackView!
@IBAction func tapsOnLikeInStack(_ sender: UIButton) {
sender.isHidden = true
}
@IBAction func tapsOnWinkInStack(_ sender: UIButton) {
sender.isHidden = true
}
func constraintsForStackView(){
stackView?.translatesAutoresizingMaskIntoConstraints = false
stackView.spacing = 8
stackView.axis = .horizontal
stackView.distribution = .fillEqually
stackView.alignment = .fill
let leading = NSLayoutConstraint(item: stackView, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1.0, constant: 8)
leading.isActive = true
let trailingToSuperView = NSLayoutConstraint(item: stackView, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1, constant: -8)
trailingToSuperView.isActive = true
let bottomToSuperView = NSLayoutConstraint(item: stackView, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: -120)
bottomToSuperView.isActive = true
}
答案 2 :(得分:0)
至于您的viewWillLayoutSubviews
代码将您的按钮放入要使用的数组中:
for btn in buttons {
if (btn.superview != nil) {
btn.translatesAutoresizingMaskIntoConstraints = false
}
}
如果您想更改视图中仍然存在的按钮的约束,请在创建约束时为它们指定标识符:
for btn in buttons {
if btn.superview != nil {
btn.translatesAutoresizingMaskIntoConstraints = false
for constraint in btn.constraints {
switch constraint.identifier {
case "winkBtnTrailing":
//do stuff like constraint = new layout constraint
//or constraint.firstItem = *new first Item to base trailing on*
break
default:
//don't do stuff?
break
}
}
}
}
正如使用button.removeFromSuperview()
的仅供参考,并未将该按钮设置为nil,只是将其从您在{/ 1}}上调用的视图中删除