view.center 命令后子视图框架未更新
Subviews frame not updating after view.center command
我有这些不同的视图,如图所示:主视图是 container
,里面是 boxSentence
,boxSentence
里面是 subView
,并且在 subView
内部带有灰色框 boxWord
的不同文本标签。然后是另一个视图 boxAnswer
,它是我创建的一个可拖动元素,只能放在 boxWord
中(我将 boxWord
传递给我的自定义 class boxAnswer
检查他的位置(帧)。
在这种情况下一切正常,只能放置 boxAnswer
inside the boxWord
然后为了调整整个视图的图形,我想把我的 subView
和他所有的实际子视图放在 boxSentence
的中心。为此,我使用了 subView.center = boxSentence.center
并获得了我想要的。
现在,当我尝试将 boxAnswer
拖放到 boxWord
的新位置时,问题就来了,它不起作用,但是如果我尝试将它拖放到 [= =18=] 是在将它移动到中心之前它确实有效。
看起来当你做subView.center = boxSentence.center
时它只影响subView
的框架,但它不影响它的子视图的框架。关于如何解决问题有什么建议吗?
代码:
// creo box dove inserire la frase
let boxSentence = UIView(frame: CGRect(x: 0, y: 0, width: container.frame.width, height: container.frame.height/2))
container.addSubview(boxSentence)
boxSentence.backgroundColor = hexStringToUIColor(hex: "#49eb34")
let subView = UIView(frame: CGRect(x: 0, y: 0, width: container.frame.width, height: 70))
let label1 = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
label1.text = esercizio.ctsex![0].first_sentence
label1.backgroundColor = UIColor.yellow
label1.sizeToFit()
let boxWord = UIView(frame: CGRect(x: label1.frame.maxX, y: 0, width: 100, height: 60))
boxWord.backgroundColor = UIColor.gray
let label2 = UILabel(frame: CGRect(x: boxWord.frame.maxX, y: 0, width: 100, height: 100))
label2.text = esercizio.ctsex![0].second_sentence
label2.backgroundColor = UIColor.yellow
label2.sizeToFit()
subView.addSubview(label1)
subView.addSubview(boxWord)
subView.addSubview(label2)
subView.backgroundColor = UIColor.purple
boxSentence.addSubview(sottoView)
subView.frame = CGRect(x: 0, y: 0, width: label2.frame.maxX-label1.frame.minX, height: 80)
subView.center = boxSentence.center
let coordrisposta = CGRect(x: boxFrase.frame.minX, y: boxFrase.frame.maxY, width: 80.0, height: 40.0)
let boxAnswer = DragObject(frame: coordrisposta, vistap: boxWord)
boxAnswer.backgroundColor = UIColor.red
container.addSubview(rispostaBox)
CLASS DragObject OF boxAnser:
import UIKit
// CLASSE CHE CREA UNA VISTA CHE PUO ESSERE SPOSTATA SOLO ALL'INTERNO DI UNA VISTA PASSATA DA PARAMETRO
class DragObject: UIView {
var vista: UIView
var initcoord: CGRect
init(frame: CGRect, vistap: UIView){
self.vista = vistap
self.initcoord = frame
super.init(frame: frame)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
print("touch began")
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
var touch : UITouch! = touches.first as UITouch?
self.center = touch.location(in: self.superview)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
var coorv = vista.frame
print(coorv)
let coord1 = (touches.first?.location(in: self.superview))!
let destinazione1 = CGPoint(x: coorv.minX, y: coorv.minY)
let destinazione2 = CGPoint(x: coorv.maxX, y: coorv.maxY)
if coord1.x > destinazione1.x && coord1.y > destinazione1.y && coord1.x < destinazione2.x && coord1.y < destinazione2.y {
print("OK")
self.frame = vista.frame
} else {
print("fuori")
self.frame = initcoord
}
}
}
UIView 的帧是它相对于它的父边界的坐标(UIView 的内部坐标系是该视图的子视图的坐标系)。
例如,我们有 UIViewController 和 2 个视图:
let redView = UIView()
redView.backgroundColor = .red
redView.frame = CGRect(x: 20, y: 20, width: 100, height: 100)
self.view.addSubview(redView)
let greenView = UIView()
greenView.backgroundColor = .green
greenView.frame = CGRect(x: 25, y:25, width:50, height: 50)
redView.addSubview(greenView)
print(redView.frame)
/*
(20.0, 20.0, 100.0, 100.0)
redView is placed self.view.bounds.origin.x + 20 and self.view.bounds.origin.y + 20
*/
print(greenView.frame)
/*
(25.0, 25.0, 50.0, 50.0)
green is placed redView.bounds.origin.x + 25 and redView.bounds.origin.y + 25
*/
print(redView.convert(greenView.frame, to: self.view))
/*
(45.0, 45.0, 50.0, 50.0)
converted frame of greenView from redViews bounds to of self.view bounds.
*/
所以 DragObject 内部的问题,您传递反映它们相对于子视图视图原点的位置的框架和视图坐标。
同时 DragObject 是容器视图的子视图,当您收到触摸坐标时,您将获得相对于容器视图的坐标。
您可以通过将 vista.frame 转换为 DragObject 超级视图坐标系来修复它。
这是覆盖 func touchesEnded(_ touches: Set, with event: UIEvent?) in DragObject
的完整代码
var coorv = vista.superview!.convert(vista.frame, to: self.superview!)
print(coorv)
let coord1 = (touches.first?.location(in: self.superview))!
let destinazione1 = CGPoint(x: coorv.minX, y: coorv.minY)
let destinazione2 = CGPoint(x: coorv.maxX, y: coorv.maxY)
if coord1.x > destinazione1.x && coord1.y > destinazione1.y && coord1.x < destinazione2.x && coord1.y < destinazione2.y {
print("OK")
self.frame = coorv
} else {
print("fuori")
self.frame = initcoord
}
我有这些不同的视图,如图所示:主视图是 container
,里面是 boxSentence
,boxSentence
里面是 subView
,并且在 subView
内部带有灰色框 boxWord
的不同文本标签。然后是另一个视图 boxAnswer
,它是我创建的一个可拖动元素,只能放在 boxWord
中(我将 boxWord
传递给我的自定义 class boxAnswer
检查他的位置(帧)。
在这种情况下一切正常,只能放置 boxAnswer
inside the boxWord
然后为了调整整个视图的图形,我想把我的 subView
和他所有的实际子视图放在 boxSentence
的中心。为此,我使用了 subView.center = boxSentence.center
并获得了我想要的。
现在,当我尝试将 boxAnswer
拖放到 boxWord
的新位置时,问题就来了,它不起作用,但是如果我尝试将它拖放到 [= =18=] 是在将它移动到中心之前它确实有效。
看起来当你做subView.center = boxSentence.center
时它只影响subView
的框架,但它不影响它的子视图的框架。关于如何解决问题有什么建议吗?
代码:
// creo box dove inserire la frase
let boxSentence = UIView(frame: CGRect(x: 0, y: 0, width: container.frame.width, height: container.frame.height/2))
container.addSubview(boxSentence)
boxSentence.backgroundColor = hexStringToUIColor(hex: "#49eb34")
let subView = UIView(frame: CGRect(x: 0, y: 0, width: container.frame.width, height: 70))
let label1 = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
label1.text = esercizio.ctsex![0].first_sentence
label1.backgroundColor = UIColor.yellow
label1.sizeToFit()
let boxWord = UIView(frame: CGRect(x: label1.frame.maxX, y: 0, width: 100, height: 60))
boxWord.backgroundColor = UIColor.gray
let label2 = UILabel(frame: CGRect(x: boxWord.frame.maxX, y: 0, width: 100, height: 100))
label2.text = esercizio.ctsex![0].second_sentence
label2.backgroundColor = UIColor.yellow
label2.sizeToFit()
subView.addSubview(label1)
subView.addSubview(boxWord)
subView.addSubview(label2)
subView.backgroundColor = UIColor.purple
boxSentence.addSubview(sottoView)
subView.frame = CGRect(x: 0, y: 0, width: label2.frame.maxX-label1.frame.minX, height: 80)
subView.center = boxSentence.center
let coordrisposta = CGRect(x: boxFrase.frame.minX, y: boxFrase.frame.maxY, width: 80.0, height: 40.0)
let boxAnswer = DragObject(frame: coordrisposta, vistap: boxWord)
boxAnswer.backgroundColor = UIColor.red
container.addSubview(rispostaBox)
CLASS DragObject OF boxAnser:
import UIKit
// CLASSE CHE CREA UNA VISTA CHE PUO ESSERE SPOSTATA SOLO ALL'INTERNO DI UNA VISTA PASSATA DA PARAMETRO
class DragObject: UIView {
var vista: UIView
var initcoord: CGRect
init(frame: CGRect, vistap: UIView){
self.vista = vistap
self.initcoord = frame
super.init(frame: frame)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
print("touch began")
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
var touch : UITouch! = touches.first as UITouch?
self.center = touch.location(in: self.superview)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
var coorv = vista.frame
print(coorv)
let coord1 = (touches.first?.location(in: self.superview))!
let destinazione1 = CGPoint(x: coorv.minX, y: coorv.minY)
let destinazione2 = CGPoint(x: coorv.maxX, y: coorv.maxY)
if coord1.x > destinazione1.x && coord1.y > destinazione1.y && coord1.x < destinazione2.x && coord1.y < destinazione2.y {
print("OK")
self.frame = vista.frame
} else {
print("fuori")
self.frame = initcoord
}
}
}
UIView 的帧是它相对于它的父边界的坐标(UIView 的内部坐标系是该视图的子视图的坐标系)。 例如,我们有 UIViewController 和 2 个视图:
let redView = UIView()
redView.backgroundColor = .red
redView.frame = CGRect(x: 20, y: 20, width: 100, height: 100)
self.view.addSubview(redView)
let greenView = UIView()
greenView.backgroundColor = .green
greenView.frame = CGRect(x: 25, y:25, width:50, height: 50)
redView.addSubview(greenView)
print(redView.frame)
/*
(20.0, 20.0, 100.0, 100.0)
redView is placed self.view.bounds.origin.x + 20 and self.view.bounds.origin.y + 20
*/
print(greenView.frame)
/*
(25.0, 25.0, 50.0, 50.0)
green is placed redView.bounds.origin.x + 25 and redView.bounds.origin.y + 25
*/
print(redView.convert(greenView.frame, to: self.view))
/*
(45.0, 45.0, 50.0, 50.0)
converted frame of greenView from redViews bounds to of self.view bounds.
*/
所以 DragObject 内部的问题,您传递反映它们相对于子视图视图原点的位置的框架和视图坐标。
同时 DragObject 是容器视图的子视图,当您收到触摸坐标时,您将获得相对于容器视图的坐标。
您可以通过将 vista.frame 转换为 DragObject 超级视图坐标系来修复它。
这是覆盖 func touchesEnded(_ touches: Set, with event: UIEvent?) in DragObject
var coorv = vista.superview!.convert(vista.frame, to: self.superview!)
print(coorv)
let coord1 = (touches.first?.location(in: self.superview))!
let destinazione1 = CGPoint(x: coorv.minX, y: coorv.minY)
let destinazione2 = CGPoint(x: coorv.maxX, y: coorv.maxY)
if coord1.x > destinazione1.x && coord1.y > destinazione1.y && coord1.x < destinazione2.x && coord1.y < destinazione2.y {
print("OK")
self.frame = coorv
} else {
print("fuori")
self.frame = initcoord
}