如果不允许约束,如何移动 CAGradientLayer 及其父 UIView 容器?
Posted
技术标签:
【中文标题】如果不允许约束,如何移动 CAGradientLayer 及其父 UIView 容器?【英文标题】:How to move a CAGradientLayer with its parent UIView container if constraints are not allowed? 【发布时间】:2018-01-24 08:55:30 【问题描述】:目前我有一个位于UITableView
上方的UIView
容器。使用从UIScrollView
的继承,我创建了容器视图的前导约束的IBOutlet
,并调整约束类似于如下:
func scrollViewDidScroll(_ scrollView: UIScrollView)
if scrollView.contentOffset.y < 0
...
containerViewLeftConstraint.constant -= abs(scrollView.contentOffset.y) * 2
else
...
containerViewLeftConstraint.constant += abs(scrollView.contentOffset.y) * 2
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool)
resetContainerViewSize()
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView)
resetContainerViewSize()
func resetContainerViewSize()
containerViewLeftConstraint.constant = 0.0
UIView.animate(withDuration: 0.4,
delay: 0.0,
usingSpringWithDamping: 0.7,
initialSpringVelocity: 0.5,
options: .curveEaseInOut,
animations:
self.view.layoutIfNeeded()
, completion: nil)
为了演示,我将容器视图的backgroundColor
设置为红色,以便直观地查看发生了什么:
我已经声明了 var gradientLayer = CAGradientLayer()
并将其作为子层添加到容器视图中,如下所示:
func createGradientOverlay()
gradientLayer.frame = containerView.frame
let colors = [UIColor.black.withAlphaComponent(0.5).cgColor,
UIColor.white.cgColor]
gradientLayer.colors = colors
gradientLayer.startPoint = CGPoint(x:0.0,
y:0.5)
gradientLayer.endPoint = CGPoint(x:1.0, y:0.5);
containerView.layer.addSublayer(gradientLayer)
但是,我得到的结果如图所示:
渐变层不粘在容器视图的边界上,看起来是浮动的。
我看过几个类似的问题:
-
CALayers didn't get resized on its UIView's bounds change. Why?
Auto Layout constraint on CALayer ios
How to get CAShapeLayer to work with constraints with swift?
How to add a CAGradientLayer to a UIView when using programmatic constraints
所有人都建议像这样使用viewDidLayoutSubviews
:
override func viewDidLayoutSubviews()
super.viewDidLayoutSubviews()
gradientLayer.frame = nameContainerView.frame
但是,渐变层似乎仍然是浮动的,并且没有遵守容器视图的约束。
我也尝试了以下方法,但无济于事:
gradientLayer.frame = nameContainerView.bounds
gradientLayer.bounds = nameContainerView.bounds
gradientLayer.frame = nameContainerView.layer.bounds
gradientLayer.frame = nameContainerView.layer.frame
我该如何解决这个问题?
【问题讨论】:
显示 resetContainerViewSize 我会告诉你如何让它粘住 @agibson007 我认为从我发布的代码中可以清楚地看到 【参考方案1】:Pangu - 如果有人想要更多信息来帮助您,那么您可能应该提供这些信息,以便他们可以帮助您。现在回答你的问题。你可以干净地完成这两种方式,如果我能看到你的功能可能是 3。
首先是创建一个使用 CAGradientLayer 作为支持层的视图,然后您可以将自动布局应用到渐变视图。这是一个你可以用几分钟的课程。
import UIKit
class GradientBackedLayer: UIView
var colors : [UIColor] = [UIColor.black.withAlphaComponent(0.5),UIColor.white]
didSet
setUpGradient()
var startPoint : CGPoint = CGPoint(x:0.0,y:0.5)
didSet
setUpGradient()
var endPoint : CGPoint = CGPoint(x:1.0, y:0.5)
didSet
setUpGradient()
override init(frame: CGRect)
super.init(frame: frame)
setUpGradient()
required init?(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
setUpGradient()
func setUpGradient()
self.backgroundColor = .clear
let cgColors = colors.map($0.cgColor)
if let gradientLayer = self.layer as? CAGradientLayer
gradientLayer.colors = cgColors
gradientLayer.startPoint = startPoint
gradientLayer.endPoint = endPoint
override class var layerClass: AnyClass
return CAGradientLayer.self
第二种是使用变换而不是改变容器上的约束,一切都会按比例缩放。如果您愿意,我会留给您解决。
【讨论】:
以上是关于如果不允许约束,如何移动 CAGradientLayer 及其父 UIView 容器?的主要内容,如果未能解决你的问题,请参考以下文章
自动布局的 Xcode 故事板问题不允许我移动对象 origin.y 值