【发布时间】:2021-05-07 06:36:03
【问题描述】:
我有一个需求,需要更改 UIView 图层的锚点,但是更改锚点后视图无法移动。 我知道当视图由 frame(CGRect:...) 定义时是可能的。像这样:
let width = SCREEN_WIDTH - 40
let view2 = UIView(frame: CGRect(x: 20, y: 300, width: width, height: 200))
view2.backgroundColor = .blue
self.view.addSubview(view2)
let oldFrame2 = view2.frame
view2.layer.anchorPoint = CGPoint(x: 0, y: 0.5)
view2.frame = oldFrame2
这行得通。
但是我的视图是由 Autolayout 定义的,我尝试了上面代码的解决方案,但它不起作用。代码:
let view1 = UIView()
view1.backgroundColor = .orange
self.view.addSubview(view1)
view1.snp.makeConstraints { (maker) in
maker.top.equalToSuperview().offset(50)
maker.leading.equalToSuperview().offset(20)
maker.trailing.equalToSuperview().offset(-20)
maker.height.equalTo(200)
}
let oldFrame1 = view1.frame
view1.layer.anchorPoint = CGPoint(x: 0, y: 0.5)
view1.frame = oldFrame1
结果是:橙色view1被移动了,改变anchorPoint后应该和蓝色view2一样。
那么谁能给我一些建议?
------------------更新答案--------------- --------------
正如@DonMag 的回答,我们可以通过在使用自动布局时更新视图而非框架的约束来实现此要求。这是 SnapKit 的代码:
let view1 = UIView()
view1.backgroundColor = .orange
view1.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(view1)
view1.snp.makeConstraints { (maker) in
maker.top.equalToSuperview().offset(100)
maker.leading.equalToSuperview().offset(20)
maker.trailing.equalToSuperview().offset(-20)
maker.height.equalTo(200)
}
// important!!!
view1.layoutIfNeeded()
let oldFrame1 = view1.frame
view1.layer.anchorPoint = CGPoint(x: 0, y: 0.5)
// update constraints by updateConstraints function
// if you use @IBOutlet NSLayoutConstraint from xib,
// you can also just set xxx.constant = yyy to update the constraints.
view1.snp.updateConstraints { (maker) in
let subOffset = oldFrame1.width * 0.5
maker.leading.equalToSuperview().offset(20 - subOffset)
maker.trailing.equalToSuperview().offset(-20 - subOffset)
}
let width = SCREEN_WIDTH - 40
let view2 = UIView(frame: CGRect(x: 20, y: 300, width: width, height: 200))
view2.backgroundColor = .blue
self.view.addSubview(view2)
let oldFrame2 = view2.frame
view2.layer.anchorPoint = CGPoint(x: 0, y: 0.5)
view2.frame = oldFrame2
另一种解决方案是通过设置translatesAutoresizingMaskIntoConstraints = true 将自动布局视图更改为框架,如下所示:
let width = SCREEN_WIDTH - 40
let view1 = UIView()
view1.backgroundColor = .orange
self.view.addSubview(view1)
// Autolayout
view1.snp.makeConstraints { (maker) in
maker.top.equalToSuperview().offset(100)
maker.leading.equalToSuperview().offset(20)
maker.trailing.equalToSuperview().offset(-20)
maker.height.equalTo(200)
}
// change autolayout to frame
view1.translatesAutoresizingMaskIntoConstraints = true
view1.frame = CGRect(x: 20, y: 100, width: width, height: 200)
let oldFrame1 = view1.frame
view1.layer.anchorPoint = CGPoint(x: 0, y: 0.5)
view1.frame = oldFrame1
let view2 = UIView(frame: CGRect(x: 20, y: 300, width: width, height: 200))
view2.backgroundColor = .blue
self.view.addSubview(view2)
let oldFrame2 = view2.frame
view2.layer.anchorPoint = CGPoint(x: 0, y: 0.5)
view2.frame = oldFrame2
【问题讨论】:
-
评论此行并检查
view1.layer.anchorPoint = CGPoint(x: 0, y: 0.5) -
这一行是我需要更改anchorPoint of view...所以我不能评论它...我只想更改anchorPoint 并且视图保持原点位置。你有什么解决办法吗?
-
你也设置了这样的锚点
view1.layer.anchorPoint = CGPoint(x: 0, y: self.view.frame.width/2) -
@RB's 不,anchorPoint 的值是从 0 到 1,它是边界大小的比率...我这里需要 0.5。不过还是谢谢你们。
标签: swift autolayout frame anchorpoint