【发布时间】:2017-11-13 02:29:34
【问题描述】:
我在 UIViewController 中添加了一个子视图。这个子视图(称为 PlayerView)应该有两种状态。一种是折叠状态,高度只有56。展开状态的高度是385。当子视图从折叠变为展开时,我希望PlayerView中的子视图改变形状和位置。
当将 PlayerView 添加到 UIViewController (MasterViewController) 时,它会像这样使用 layoutSubviews():
override func layoutSubviews() {
super.layoutSubviews()
backgroundColor = UIColor(red: 24/255, green: 24/255, blue: 24/255, alpha: 1)
roundCorners([.topLeft, .topRight], radius: 10)
addSubview(albumImage)
addSubview(songTitleLabel)
addSubview(songArtistLabel)
addSubview(playPauseButton)
_ = albumImage.anchor(nil, left: leftAnchor, bottom: nil, right: nil, topConstant: 0, leftConstant: 20, bottomConstant: 0, rightConstant: 0, widthConstant: 40, heightConstant: 40)
albumImage.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
_ = playPauseButton.anchor(nil, left: nil, bottom: nil, right: rightAnchor, topConstant: 0, leftConstant: 0, bottomConstant: 0, rightConstant: 30, widthConstant: 22, heightConstant: 22)
_ = songTitleLabel.anchor(albumImage.topAnchor, left: albumImage.rightAnchor, bottom: nil, right: playPauseButton.leftAnchor, topConstant: 0, leftConstant: 8, bottomConstant: 0, rightConstant: 8, widthConstant: songTitleLabel.frame.width, heightConstant: songTitleLabel.frame.height)
_ = songArtistLabel.anchor(songTitleLabel.bottomAnchor, left: songTitleLabel.leftAnchor, bottom: nil, right: playPauseButton.leftAnchor, topConstant: 2, leftConstant: 8, bottomConstant: 0, rightConstant: 8, widthConstant: songArtistLabel.frame.width, heightConstant: songArtistLabel.frame.height)
playPauseButton.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
}
当按下折叠视图时,它应该展开。以下是我的做法(在我的 MasterViewController 中):
let pv = PlayerView()
func expandPlayerView() {
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
self.view.layoutIfNeeded()
self.pv.frame = CGRect(x: 0, y: CGFloat((self.view.frame.maxY) - 352), width: 375, height: 350)
self.pv.changePlayerView()
self.view.layoutSubviews()
}) { (true) in
}
}
changePlayerView() 函数定义如下:
func changePlayerView() {
subviews.forEach({$0.removeFromSuperview()})
addSubview(playPauseButton)
playPauseButton.removeConstraints(playPauseButton.constraints)
_ = playPauseButton.anchor(nil, left: nil, bottom: bottomAnchor, right: nil, topConstant: 0, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: 22, heightConstant: 22)
playPauseButton.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
}
执行完所有这些代码后会发生什么:
1.playerView扩展为385罚款
2.从playerView中移除所有其他子视图
3.播放暂停按钮几乎占据了整个PlayerView子view,不符合其22的宽高约束
我需要做什么才能让 playPauseButton 符合它的所有约束?
编辑:
.anchor 函数在 UIView 的扩展中定义如下:
func anchor(_ top: NSLayoutYAxisAnchor? = nil, left: NSLayoutXAxisAnchor? = nil, bottom: NSLayoutYAxisAnchor? = nil, right: NSLayoutXAxisAnchor? = nil, topConstant: CGFloat = 0, leftConstant: CGFloat = 0, bottomConstant: CGFloat = 0, rightConstant: CGFloat = 0, widthConstant: CGFloat = 0, heightConstant: CGFloat = 0) -> [NSLayoutConstraint] {
translatesAutoresizingMaskIntoConstraints = false
var anchors = [NSLayoutConstraint]()
if let top = top{
anchors.append(topAnchor.constraint(equalTo: top, constant: topConstant))
}
if let left = left{
anchors.append(leftAnchor.constraint(equalTo: left, constant: leftConstant))
}
if let bottom = bottom{
anchors.append(bottomAnchor.constraint(equalTo: bottom, constant: -bottomConstant))
}
if let right = right{
anchors.append(rightAnchor.constraint(equalTo: right, constant: -rightConstant))
}
if widthConstant > 0{
anchors.append(widthAnchor.constraint(equalToConstant: widthConstant))
}
if heightConstant > 0{
anchors.append(heightAnchor.constraint(equalToConstant: heightConstant))
}
anchors.forEach({$0.isActive = true})
return anchors
}
【问题讨论】:
-
我很难通过您的代码 - 可能只是编码风格的差异。但是 - 我看到 no 定义或命名约束 也没有 现有约束数组的任何激活/停用。这是在定义约束之后更改约束的两种常用方法。我错过了什么吗?换句话说,将事物分解为您希望更改的 single 约束 - 例如高度或宽度,您打算如何(以及何时)更改它?
-
查看底部函数‘anchor’。这就是我设置约束的方式
-
我做到了。仍然过得很艰难。 具体你想做什么? 具体是什么问题?再说一次,发生了什么变化? (更好的是,你能给我一些我可以实际复制的东西吗?编辑:我已经设置了改变的约束。滑动菜单、方向改变等。你发布的代码中没有任何意义!我得到您的
anchor函数将 everything 设置为isActive = true。这与您的问题标题不符 - “按下按钮时更改约束”。 -
问题是,当我更改约束(通过运行 changePlayerView)时,playPauseButton 按钮不是 22x22。它占据了整个 playerView,即 375x385。你能通过我给你的代码告诉你原因吗?如果需要,我可以提供更多代码